mirror of
https://github.com/varvet/pundit.git
synced 2022-11-09 12:30:11 -05:00
Add permitted attributes helper, closes #141
See discussion in #141. This provides a convenient helper which aids in permitting attributes in the controller.
This commit is contained in:
parent
3bd1d74c7f
commit
68372c9c17
5 changed files with 53 additions and 8 deletions
31
README.md
31
README.md
|
@ -481,10 +481,9 @@ end
|
|||
|
||||
In Rails 4 (or Rails 3.2 with the
|
||||
[strong_parameters](https://github.com/rails/strong_parameters) gem),
|
||||
mass-assignment protection is handled in the controller.
|
||||
Pundit helps you permit different users to set different attributes. Don't
|
||||
forget to provide your policy an instance of object or a class so correct
|
||||
permissions could be loaded.
|
||||
mass-assignment protection is handled in the controller. With Pundit you can
|
||||
control which attributes a user has access to update via your policies. You can
|
||||
set up a `permitted_attributes` method in your policy like this:
|
||||
|
||||
```ruby
|
||||
# app/policies/post_policy.rb
|
||||
|
@ -497,12 +496,16 @@ class PostPolicy < ApplicationPolicy
|
|||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
You can now retrieve these attributes from the policy:
|
||||
|
||||
```ruby
|
||||
# app/controllers/posts_controller.rb
|
||||
class PostsController < ApplicationController
|
||||
def update
|
||||
@post = Post.find(params[:id])
|
||||
if @post.update(post_params)
|
||||
if @post.update_attributes(post_params)
|
||||
redirect_to @post
|
||||
else
|
||||
render :edit
|
||||
|
@ -512,7 +515,23 @@ class PostsController < ApplicationController
|
|||
private
|
||||
|
||||
def post_params
|
||||
params.require(:post).permit(*policy(@post || Post).permitted_attributes)
|
||||
params.require(:post).permit(policy(@post).permitted_attributes)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
However, this is a bit cumbersome, so Pundit provides a convenient helper method:
|
||||
|
||||
```ruby
|
||||
# app/controllers/posts_controller.rb
|
||||
class PostsController < ApplicationController
|
||||
def update
|
||||
@post = Post.find(params[:id])
|
||||
if @post.update_attributes(permitted_attributes(@post))
|
||||
redirect_to @post
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
|
|
@ -77,6 +77,7 @@ module Pundit
|
|||
hide_action :authorize
|
||||
hide_action :verify_authorized
|
||||
hide_action :verify_policy_scoped
|
||||
hide_action :permitted_attributes
|
||||
hide_action :pundit_user
|
||||
end
|
||||
end
|
||||
|
@ -115,6 +116,11 @@ module Pundit
|
|||
policies[record] ||= Pundit.policy!(pundit_user, record)
|
||||
end
|
||||
|
||||
def permitted_attributes(record)
|
||||
name = record.class.to_s.demodulize.underscore
|
||||
params.require(name).permit(policy(record).permitted_attributes)
|
||||
end
|
||||
|
||||
def policies
|
||||
@_pundit_policies ||= {}
|
||||
end
|
||||
|
|
|
@ -20,6 +20,7 @@ Gem::Specification.new do |gem|
|
|||
|
||||
gem.add_dependency "activesupport", ">= 3.0.0"
|
||||
gem.add_development_dependency "activemodel", ">= 3.0.0"
|
||||
gem.add_development_dependency "actionpack", ">= 3.0.0"
|
||||
gem.add_development_dependency "bundler", "~> 1.3"
|
||||
gem.add_development_dependency "rspec", ">=2.0.0"
|
||||
gem.add_development_dependency "pry"
|
||||
|
|
|
@ -271,7 +271,7 @@ describe Pundit do
|
|||
end
|
||||
end
|
||||
|
||||
describe ".policy" do
|
||||
describe "#policy" do
|
||||
it "returns an instantiated policy" do
|
||||
policy = controller.policy(post)
|
||||
expect(policy.user).to eq user
|
||||
|
@ -290,7 +290,7 @@ describe Pundit do
|
|||
end
|
||||
end
|
||||
|
||||
describe ".policy_scope" do
|
||||
describe "#policy_scope" do
|
||||
it "returns an instantiated policy scope" do
|
||||
expect(controller.policy_scope(Post)).to eq :published
|
||||
end
|
||||
|
@ -306,4 +306,13 @@ describe Pundit do
|
|||
expect(controller.policy_scope(Post)).to eq new_scope
|
||||
end
|
||||
end
|
||||
|
||||
describe "#permitted_attributes" do
|
||||
it "checks policy for permitted attributes" do
|
||||
params = ActionController::Parameters.new({ action: 'update', post: { title: 'Hello', votes: 5, admin: true } })
|
||||
|
||||
expect(Controller.new(user, params).permitted_attributes(post)).to eq({ 'title' => 'Hello', 'votes' => 5 })
|
||||
expect(Controller.new(double, params).permitted_attributes(post)).to eq({ 'votes' => 5 })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
require "pundit"
|
||||
require "pundit/rspec"
|
||||
|
||||
require "rack"
|
||||
require "rack/test"
|
||||
require "pry"
|
||||
require "active_support"
|
||||
require "active_support/core_ext"
|
||||
require "active_model/naming"
|
||||
require "action_controller/metal/strong_parameters"
|
||||
|
||||
I18n.enforce_available_locales = false
|
||||
|
||||
|
@ -32,6 +35,13 @@ class PostPolicy < Struct.new(:user, :post)
|
|||
def show?
|
||||
true
|
||||
end
|
||||
def permitted_attributes
|
||||
if post.user == user
|
||||
[:title, :votes]
|
||||
else
|
||||
[:votes]
|
||||
end
|
||||
end
|
||||
end
|
||||
class PostPolicy::Scope < Struct.new(:user, :scope)
|
||||
def resolve
|
||||
|
|
Loading…
Reference in a new issue