Forked from christiannelson/application_controller.rb
Last active
May 21, 2020 18:28
-
-
Save mkhairi/5148a107d2ed2d8d797f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ApplicationController < ActionController::Base | |
include Pundit | |
# Verify that controller actions are authorized. Optional, but good. | |
after_filter :verify_authorized, except: :index | |
after_filter :verify_policy_scoped, only: :index | |
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized | |
private | |
def user_not_authorized | |
flash[:error] = "You are not authorized to perform this action." | |
redirect_to request.headers["Referer"] || root_path | |
end | |
# ... | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CandidatesController < ApplicationController | |
# This controller defines some custom actions. | |
after_filter :verify_authorized, except: [:search, :index, :dashboard] | |
after_filter :verify_policy_scoped, only: [:search, :index, :dashboard] | |
def dashboard | |
# policy_scope returns a scope configured according to the | |
# CandidatePolicy. | |
@candidates = policy_scope(Candidate) | |
@candidates.includes(stages: [:notes]).references(:stages) | |
end | |
def show | |
@candidate = Candidate.find(params[:id]) | |
authorize @candidate | |
end | |
def star | |
@candidate = Candidate.find(params[:id]) | |
# If the user can update a candidate, they can also "star" them. | |
authorize @candidate, :update? | |
@candidate.update_attribute(:starred, true) | |
render partial: 'candidates/star', locals: { candidate: @candidate } | |
end | |
# ... | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/ Truncated for brevity. | |
- @candidates.each do |candidate| | |
tr | |
td= link_to_if policy(candidate).show?, candidate.name, candidate_path(candidate) | |
td | |
- if policy(candidate).edit? | |
= link_to 'Edit', edit_candidate_path(candidate) | |
- if policy(candidate).destroy? | |
= link_to 'Destroy', candidate_path(candidate), method: :delete | |
- if policy(Candidate.new).create? | |
= link_to 'New Candidate', new_candidate_path |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Styled for brevity... | |
class NotePolicy < ApplicationPolicy | |
def show? ; true; end | |
def create? ; true; end | |
def update? ; record.user == user; end | |
def destroy?; record.user == user; end | |
end | |
# And a top-level policy for setting defaults. | |
class ApplicationPolicy | |
attr_reader :user, # User performing the action | |
:record # Instance upon which action is performed | |
def initialize(user, record) | |
raise Pundit::NotAuthorizedError, "Must be signed in." unless user | |
@user = user | |
@record = record | |
end | |
def index? ; false; end | |
def show? ; scope.where(id: record.id).exists?; end | |
def new? ; create?; end | |
def create? ; false; end | |
def edit? ; update?; end | |
def update? ; false; end | |
def destroy?; false; end | |
def scope | |
Pundit.policy_scope!(user, record.class) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe NotePolicy do | |
subject { NotePolicy.new(current_user, note) } | |
context "for a user" do | |
let(:current_user) { build_stubbed :user } | |
context "creating a new note" do | |
let(:note) { Note.new } | |
it { should permit(:new) } | |
it { should permit(:create) } | |
end | |
context "with a note someone else created" do | |
let(:note) { build_stubbed :note, user: build(:user) } | |
it { should permit(:show) } | |
it { should_not permit(:edit) } | |
it { should_not permit(:update) } | |
it { should_not permit(:destroy) } | |
end | |
context "with a note that I created" do | |
let(:note) { build_stubbed :note, user: current_user } | |
it { should permit(:show) } | |
it { should permit(:edit) } | |
it { should permit(:update) } | |
it { should permit(:destroy) } | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module PunditViewPolicy | |
extend ActiveSupport::Concern | |
included do | |
before do | |
controller.singleton_class.class_eval do | |
def policy(instance) | |
Class.new do | |
def method_missing(*args, &block); true; end | |
end.new | |
end | |
helper_method :policy | |
end | |
end | |
end | |
end | |
RSpec.configure do |config| | |
config.include PunditViewPolicy, type: :view | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe "users/show" do | |
before(:each) do | |
user = assign(:user, build_stubbed(:user)) | |
controller.stub(:current_user).and_return user | |
end | |
it "renders the destroy action" do | |
# New Rspec syntax | |
allow(view).to receive(:policy).and_return double(edit?: false, destroy?: true) | |
render | |
expect(rendered).to match 'Destroy' | |
end | |
it "does not render the destroy action" do | |
# Old Rspec syntax | |
view.stub(:policy).and_return double(edit?: false, destroy?: false) | |
render | |
expect(rendered).to_not match 'Destroy' | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CandidatePolicy < ApplicationPolicy | |
# ... | |
def permitted_attributes | |
if user.manager? | |
[:name, :salary, :equity] | |
else | |
[:name] | |
end | |
end | |
end | |
class CandidatesController < ApplicationController | |
# ... | |
def update | |
# ... | |
if @candidate.update_attributes(candidate_attributes) | |
# ... | |
end | |
private | |
def candidate_attributes | |
params.require(:candidate) | |
.permit(policy(@candidate).permitted_attributes) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment