Dwayne  XD
Dwayne XD

Reputation: 45

CanCanCan load_and_authorize_resource

I have two questions in 1:

  1. load_and_authorize_resource is not working in my Pokemon controller. If I am understanding the documentaion load_and_authorize_resource should prevent a user from visiting a route / action they aren't authorized to access. Here is the code for the controller:
class PokemonsController < ApplicationController
  load_and_authorize_resource
  
  def update
    if @pokemon.update_attributes(pokemon_params)
      flash[:success] = 'Pokemon was updated!'
      redirect_to root_path
    else
      render 'edit'
    end
  end

  
  def create
    @pokemon = Pokemon.new(pokemon_params)
    @pokemon.user_id = current_user.id
    @pokemon.trainer_id = Trainer.first.id

    if @pokemon.save
      flash[:success] = "Nice job! #{@pokemon.name} was created!"
      redirect_to pokemons_path
    else
      flash[:danger] = "Hmmm try that again."
      render :new
    end
  end

  def show
    @pokemon = Pokemon.find_by_slug(params[:slug])
  end

  def destroy
    if @pokemon.destroy
      flash[:success] = 'Congrats, you destroyed a pokemon😔'
    else
      flash[:warning] = 'I couldnt destroy this pokemon...'
    end
    redirect_to root_path
  end
 
  private

  def pokemon_params
    params.require(:pokemon).permit(
      :name,
      :pkmn_type,
      :level,
      :attack,
      :defense, 
      :speed, 
      :pokedex, 
      :sp_attack, 
      :sp_defense
    )
  end

end


And here is the ability.rb model:

class Ability
  include CanCan::Ability

  def initialize(user)
      user ||= User.new # guest user (not logged in)
      if user.admin?
        can :manage, :all
      else
        can :manage, Pokemon, user_id: user.id
        can :read, :all
      end
  end
end

I have logged out of the application so there is no current_user / session available, but I am still able to visit the edit view for a pokemon. Any idea whats going on?

Question 2: How would I go about debugging this for future reference ?

Here is a link to the repo if it helps at all. Thanks in advance😊

Upvotes: 1

Views: 1836

Answers (1)

Roman Alekseiev
Roman Alekseiev

Reputation: 1920

I've download your repo. First of all your sign up page is not working properly. There are no first/last name fields which are required. I think you can handle them in future. What about your question, cancancan works fine when I changed your slug routes to default id routes. Here is error when I tried to edit pokemon which belongs to different user:

CanCan::AccessDenied - You are not authorized to access this page.:
Started GET "/pokemons/2/..." for ::1 at 2019-12-23 11:27:37 +0200

When I returned slug it breaks this behaviour and I can edit all pokemons. So issue is not in the CanCanCan but in configurations of slug. If you do not want to change routes for default or to use FriendlyId I recommend you to use your controllers actions like this:

  def edit
    @pokemon = Pokemon.find_by_slug(params[:slug])
    authorize! :edit, @pokemon
  end

NOTE: you have to remove line load_and_authorize_resource

This configuration also returns correct error when trying to edit pokemon which does not belong to user:

enter image description here

I hope I helped a little bit.

Upvotes: 2

Related Questions