nathanl / authority

*CURRENTLY UNMAINTAINED*. Authority helps you authorize actions in your Rails app. It's ORM-neutral and has very little fancy syntax; just group your models under one or more Authorizer classes and write plain Ruby methods on them.
MIT License
1.21k stars 67 forks source link

Getting Started #26

Closed weblee closed 11 years ago

weblee commented 11 years ago

OK so I am being thick but I cant get this to work and hopefully you can point me in the right direction. I just keep getting the error below when going to path listings/new

undefined method `can_create?' for nil:NilClass
User Model
class User < ActiveRecord::Base
  include Authority::UserAbilities
  ...
Listings Controller
class ListingsController < ApplicationController
  authorize_actions_for Listing
  ....
Listing Model
class Listing < ActiveRecord::Base
  include Authority::Abilities
  ....
ListingAuthorizer
class ListingAuthorizer < ApplicationAuthorizer
  def creatable_by?(user)
    true
  end

  def self.creatable_by?(user)
    true
  end

end
Authority.rb
Authority.configure do |config|
  config.user_method = :current_user
  config.controller_action_map = {
    :index   => 'read',
    :show    => 'read',
    :new     => 'create',
    :create  => 'create',
    :edit    => 'update',
    :update  => 'update',
    :destroy => 'delete'
  }
  config.abilities =  {
    :create => 'creatable',
    :read   => 'readable',
    :update => 'updatable',
    :delete => 'deletable'
  }
end
ApplicationAuthorizer.rb
class ApplicationAuthorizer < Authority::Authorizer
  def self.default(adjective, user)
    false
  end
end

Hope you can get me on the right path !

nathanl commented 11 years ago

@weblee - No worries. Looks like you have things set up fine for Authority.

The message you're getting: undefined method 'can_create?' for nil:NilClass tells me that somewhere you're probably calling @user.can_create?(Listing), and for whatever reason, @user is nil. Or maybe you have a method like current_user that's returning nil, and you're calling current_user.can_create?

So although your user instance has a can_create? method, nil doesn't, and that's what you've got, not an actual user object.

weblee commented 11 years ago

TY!!!!

My current_user had an issue but I stil cant access the listings/new actions

So in my ListingAuthorizer I have

class ListingAuthorizer < ApplicationAuthorizer
  def creatable_by?(user)
    true  ## tmp to test
  end
end

Everything else is the same from my first post.

If the above is correct the current_user should be able to see and use the create method?

nathanl commented 11 years ago

@weblee - The best way to figure it the right rules for your authorizers is to experiment in the Rails console. Instantiate a user who should be able to do something, then check if it can_create?(Listing), or can_delete?(some_listing), or whatever.

weblee commented 11 years ago

Hi Nathanl, One last question I hope you dont mind me asking.

I think I found the issue but confused to if its correct.

I could not get Authority to check the user against my listing authority class until I changed the class name on the authorize_actions_for

Basically I had this.

class ListingsController < ApplicationController
  authorize_actions_for Listing
  ...

But when changed to the below it worked

class ListingsController < ApplicationController
  authorize_actions_for ListingAuthorizer
  ...

But in your example docs you never added Authorize ie,

class LlamasController < ApplicationController
  authorize_actions_for Llama
  ....

Should it have been

class LlamasController < ApplicationController
  authorize_actions_for LlamaAuthorizer
  ....

If it shouldn't then I still have problems.

Again excuse me for being thick !

nathanl commented 11 years ago

@weblee - You should be able to do authorizer_actions_for Listing, as the README shows.

What authorizer is your Listing model expecting to use? It starts out assuming ApplicationAuthorizer. If you want it to use ListingAuthorizer, you have to set the authorizer_name accordingly. Maybe that's the issue? You can check it in the Rails console: Listing.authorizer_name.

weblee commented 11 years ago

Ok here goes.

2.0.0p0 :001 > Listing.authorizer_name
# 2013-03-18 18:51:03:058 [HEAD] ("listings")
#
curl -I "http://localhost:9200/listings"

# 2013-03-18 18:51:03:058 [200]

 => "ApplicationAuthorizer" 

these are my files to make sure Im sane!

app/models/listing.rb

class Listing < ActiveRecord::Base
  include Authority::Abilities
  ...

app/controllers/listings_controller.rb

class ListingsController < ApplicationController
  authorize_actions_for Listing
  ...

app/authorizers/listing_authorizer.rb

class ListingAuthorizer < ApplicationAuthorizer
  def creatable_by?(user)
    user.role?(:proprietor) || user.role?(:admin)
  end
end

app/authorizers/application_authorizer.rb

class ApplicationAuthorizer < Authority::Authorizer
  def self.default(adjective, user)
    false
  end
end

So it shows its not picking up the ListingAuthorizer. Am I correct or wrong ??

nathanl commented 11 years ago

@weblee - As I said before:

If you want it to use ListingAuthorizer, you have to set the authorizer_name accordingly.

For example:

class Listing < ActiveRecord::Base
  include Authority::Abilities

  # Without this, 'ApplicationAuthorizer' is assumed
  self.authorizer_name = 'ListingAuthorizer'
  ...

Authority does not automatically do this because part of the design is that multiple models can use the same authorizer.

weblee commented 11 years ago

God I do feel so stupid. I should learn to read !!!!!!

Thank you Nathanl for being patient. This gem is wicked!!!

nathanl commented 11 years ago

@weblee - No problem. :) Thanks, and good luck!

nathanl commented 11 years ago

@weblee - I just released version 2.5.0, which I think would have made things a little more intuitive for you. See the CHANGELOG file for details.

weblee commented 11 years ago

haha Perfect. I was actually thinking about that as an idea when we actually resolved the issue. Plus it makes sense for dummies like me. :-) TY