smallseo.info

cancan

Authorization Gem for Ruby on Rails.

Cancan accessible_by

What exactly is happening when I do:

@patient.course_enrollments.accessible_by(current_ability)

What seems to happen is I get course_enrollments where course.client_id = user.client.id, I just don't understand how accessible_by works.

# ability.rb
can :manage, CourseEnrollment, :course => {:client_id => user.client.id}

Source: (StackOverflow)

How to do integration testing with RSpec and Devise/CanCan?

If I have a Devise model User, of which only those users with role :admin are allowed to view a certain url, how can I write an RSpec integration test to check that the status returns 200 for that url?

def login(user)
  post user_session_path, :email => user.email, :password => 'password'
end

This was pseudo-suggested in the answer to this question: Stubbing authentication in request spec, but I can't for the life of me get it to work with devise. CanCan is receiving a nil User when checking Ability, which doesn't have the correct permissions, naturally.

There's no access to the controller in integration specs, so I can't stub current_user, but I'd like to do something like this.

describe "GET /users" do
  it "should be able to get" do
    clear_users_and_add_admin #does what it says...
    login(admin)
    get users_path
    response.status.should be(200)
  end
end

NOTE!!!: all this has changed since the question was asked. The current best way to do this is here: http://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara


Source: (StackOverflow)

Access CanCan's `can?` method from a model

You can get the current_user's permissions from a view or controller using can? in this fashion:

  <% if can? :update, @article %>
    <%= link_to "Edit", edit_article_path(@article) %>
  <% end %>

How can I access this functionality from a model using this syntax:

user.can?(:update, @article)

Source: (StackOverflow)

How to create the first (Admin) user (CanCan and Devise)?

I made authentication in my Rails 3 app fallowed by Tony's tutorial

I don't want public registrations on my app, just to create new users with Admin account, but I can't create Admin account manually, because in table Users there is encrypted password and salt that must to be generated, and I don't know how :|


Source: (StackOverflow)

Testing views that use CanCan and Devise with RSpec

I was trying to test a simple index view, which has following code inside:

- if can? :destroy, MyModel
  %th Options

MyModelsController has following options (Inherited Resources + CanCan + Devise):

class MyModelsController < ApplicationController
  inherit_resources
  nested_belongs_to :mymodel
  before_filter :authenticate_user!
  load_and_authorize_resource :project
  load_and_authorize_resource :mymodel, :through => :project

When running specs, it crashes at the line - if can? :destroy, MyModel

Failure/Error: render
   ActionView::Template::Error:
      undefined method `authenticate' for nil:NilClass

There's no traceback, nothing to base on...

I thought that maybe I'm not authorized and signed when testing views, but Devise::TestHelpers should only be included in controller tests (and that's how I have it).

I was trying to override method can? in both Ability and the controller, but that gave no effect.


Source: (StackOverflow)

CanCan: limiting a user's ability to set certain model attributes based on their role

I have a Post model with a :published attribute (boolean) and a User model with a role attribute (string). There are three roles: ROLES = %w[admin publisher author]

I don't want users whose role is author to be capable of setting, or editing, the :published field on the Post model.

I'm using CanCan (and RailsAdmin gem) and my simplified Ability.rb file looks like this:

class Ability
  include CanCan::Ability
  def initialize(user)
    user ||= User.new

    if user.role? :admin
      can :manage, :all
    elsif user.role? :publisher
      can :manage, Post
    elsif user.role? :author
      # I want to prevent these guys from setting the :published attribute
    end

  end
end

Anyone got any tips for doing this sort of thing?


Source: (StackOverflow)

How to access 'can?' method from within cell?

I'm using cancan and cells gems in my ruby-on-rails project. How to access can? method from within cell? Thanks.


Source: (StackOverflow)

Is it possible to use cancan with two ability class

I'm using rails 3.0.9, cancan 1.6.7 and devise 1.4.8

I'm using two devise models(User and Admin) for different log-in and registration process

So I want to divide the abilities depend upon the logged-in user(resource), because there are more than 70 models and only 10 models are common for both type of users(here more than 50 models and views are only used by Admin users)

I want to implement two Ability class(UserAbility and AdminAbility) and the devise helper method current_user/current_admin should be passed to UserAbility/AdminAbility

Example:

In ApplicationController.rb file

    def current_ability
        if current_user
            @current_ability = UserAbility.new(current_user)
        elsif current_admin
            @current_ability = AdminAbility.new(current_admin)
        end
    end

From the above my questions,

  1. Is multiple ability class is possible in cancan, if possible then how to create it because I tried

    rails g cancan:user_ability

    but I got error as Could not find generator cancan:user_ability.

  2. How to choose the appropriate Ability class for the logged-in User/Admin.

  3. If a controller is accessed by both the User and Admin, then how can I get the currently logged-in User/Admin's object

Is there any other solution for this?

Any one please help to solve this


Source: (StackOverflow)

Rails4 authorization strategies

When it comes to Authorization/Authentication devise + cancan are usually my gems of choice. After the release of Rails4's strong parameters I've been looking into using the cancan_strong_parameters gem.

I can't shake the feeling that this approach seems a bit 'hacky'. The other options seems to be TheRole gem or simply rolling my own auth from scratch.

Was hoping anyone with first hand experience here could give a few pointers on how they tackled the problem, what problems the faced and where each approach fell short (if anywhere).

I know this isn't a clean cut StackOverflow typed question, but there doesn't seem to be much info regarding this subject when Googling. Thanks.


Source: (StackOverflow)

Context aware authorization using CanCan

I want to use CanCan to handle my permissions. My site has many different permissions levels, and most of them are context aware. For instance, Here are the relations in my 3 main models:

class User < ActiveRecord::Base
  has_many :league_relations
  has_many :leagues, :through => :league_relations
end

class League < ActiveRecord::Base
  has_many :league_relations
  has_many :users, :through => :league_relations
end

class LeagueRelation < ActiveRecord::Base
  belongs_to :user
  belongs_to :league
end

Note, LeagueRelations is a nested resource of Leagues. What I want to do is allow a user to modify leagues, and gauge each user's authorization based off of data stored in league_relation. I would then like a user to modify league relation, based only the data stored in the user model.

To be succinct: I basically want LeagueRelations to be used to authorize League actions, and Users to be used to authorize LeagueRelations actions. i.e. league_relation.owner = true to delete a League, but user.owner? must be true to delete a LeagueRelation. How can I authorize based on the attributes of league_relation when inside the league controller, and authorize other actions in other controllers on other models. Please leave a comment if you need more clarification.

Thanks.


Source: (StackOverflow)

CanCan - Access denied - Way to make CanCan Specify in the LOG Why?

I'm working to implement CanCan. For some reason CanCan keeps giving me Access Denied when I try to get specific about model permissions. And I can't figure out why.

Is there a way to get CanCan to be specific, perhaps in the logs or in development about Why Access is denied? something like, No Read Ability to XXX Model.

That would be helpful for debugging.

Thanks


Source: (StackOverflow)

Why is this rspec request spec not updating the model?

I have a requests spec for interactions with the User model. I want to make sure that Users with the Admin role can create/edit/destroy Users. I'm having a problem right now where the Edit action does not update the user. Everything works properly when I manually go through the actions on the site itself, but the tests fail to update the user.

Here's my spec:

it 'edits a user' do
  @user = FactoryGirl.create(:user)
  visit new_user_session_path unless current_path == new_user_session_path
  fill_in "Email", :with => @user.email
  fill_in "Password", :with => @user.password
  click_button "Sign In"
  user_to_edit = FactoryGirl.create(:user, first_name: "John", last_name: "Smith")
  visit edit_user_path(user_to_edit) unless current_path == edit_user_path(user_to_edit)
  fill_in 'user_last_name', with: "Changed"
  expect{
    click_button "Do it"
  }.to change { user_to_edit.last_name }.from("Smith").to("Changed")
  page.should have_content "John Changed"
end

The error that I get is:

Failure/Error: expect{
       result should have been changed to "Changed", but is now "Smith"

If I change the last few lines of the test to this:

  fill_in 'user_last_name', with: "Changed"
  click_button "Do it"
  page.should have_content "John Changed"

Then the test succeeds. This doesn't seem right, since the page should not display "John Changed" if user_to_edit was not updated.

My Delete request spec works fine:

it "deletes a user" do
  @user = FactoryGirl.create(:user)
  visit new_user_session_path unless current_path == new_user_session_path
  fill_in "Email", :with => @user.email
  fill_in "Password", :with => @user.password
  click_button "Sign In"
  user_to_delete = FactoryGirl.create(:user, first_name: "John", last_name: "Smith")
  visit users_path unless current_path == users_path
  expect{
    within ".user_#{user_to_delete.id}" do
      click_link 'Delete'
    end
  }.to change(User,:count).by(-1)
  page.should_not have_content "John Smith"
end

I have a user model:

class User < ActiveRecord::Base
  ROLES = %w[renter landlord admin]
  devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
  attr_accessible :email, :password, :password_confirmation :first_name, :last_name, :role

  validates :password, :presence => true, :on => :create
  validates :first_name, :presence => true
  validates :last_name, :presence => true

  before_save :set_phones

  def set_phones
    self.fax = Phoner::Phone.parse(self.fax).format("%a%n") unless self.fax.blank?
    self.land_phone = Phoner::Phone.parse(self.land_phone).format("%a%n") unless land_phone.blank?
    self.mobile_phone = Phoner::Phone.parse(self.mobile_phone).format("%a%n") unless mobile_phone.blank?
  end
end

I have this factory:

require 'faker'

FactoryGirl.define do
  factory :user do |f|
    f.first_name { Faker::Name.first_name }
    f.last_name { Faker::Name.last_name }
    f.email {Faker::Internet.email}
    f.password { "oq2847hrowihgfoigq278o4r7qgo4" }
    f.role { "admin" }
  end
end

I have these actions in my user controller:

  def edit
    @user = User.find_by_id(params[:id])

    respond_to do |format|
      format.html
    end
  end

  def update
    if params[:user][:password].blank?
      [:password,:password_confirmation].collect{|p| params[:user].delete(p) }
    end

    respond_to do |format|
      if @user.errors[:base].empty? and @user.update_attributes(params[:user])
        flash.now[:notice] = "Your account has been updated"
        format.html { render :action => :show }
      else
        format.html { render :action => :edit, :status => :unprocessable_entity }
      end
    end
  end

The routes.rb file is also relevant, since I'm using Devise and have a custom Users Controller:

  devise_for :users, :skip => [:sessions, :registrations]

  devise_scope :user do
    get "login" => "devise/sessions#new", :as => :new_user_session
    post 'login' => 'devise/sessions#create', :as => :user_session
    delete "logout" => "devise/sessions#destroy", :as => :destroy_user_session
    get "signup" => "devise/registrations#new", :as => :new_user_registration
    put "update-registration" => "devise/registrations#update", :as => :update_user_registration
    delete "delete-registration" => "devise/registrations#destroy", :as => :delete_user_registration
    get "edit-registration" => "devise/registrations#edit", :as => :edit_user_registration
    get "cancel-registration" => "devise/registrations#cancel", :as => :cancel_user_registration
    post "create-registration" => "devise/registrations#create", :as => :user_registration
  end

  resources :users, :controller => "users"

Source: (StackOverflow)

Admin Authorization w/ CanCan

A have a bunch of controllers w/ the Admin namespace. I want to restrict access to these unless the user is an admin. Is there a way to do this using CanCan without having to call unautorized! in every method of every controller?


Source: (StackOverflow)

Serialize permissions (e.g. CanCan) with active_model_serializers

How do I serialize permissions with active_model_serializers? I don't have access to current_user or the can? method in models and serializers.


Source: (StackOverflow)

How can I use RSpec to test the response code on a CanCan failed authorization?

I'm working on a rails project in which I use CanCan to authorize my resources. When a user is not signed in and tries to submit a "talk" (via an ajax form submission), CanCan correctly raises a 401 with {"status":"error","message":"You must be logged in to do that!"} as the response (I have verified this in the browser using firebug). However, in my tests get a 302 response code rather than a 401:

class TalksController < ApplicationController
  authorize_resource

  def create
    @talk = current_user.talks.build(params[:talk])

    respond_to do |format|
      if @talk.save
        response = { :redirect => talk_path(@talk) }
        format.html { redirect_to @talk, notice: 'Talk was successfully created.' }
        format.json { render json: response, status: :created,  }
      else
        format.html { render action: "new" }
        format.json { render json: @talk.errors, status: :unprocessable_entity }
      end
    end
  end
end

talks_controller_spec.rb:

describe TalksController do
  describe "POST create" do
    context "when not signed in" do
      it "should not assign talk" do
        post :create
        assigns[:talk].should be_nil
      end
      it "should respond with a 401" do
        post :create
        response.response_code.should == 401
      end
    end
  end
end

The first example included here is successful (assigns[:talk] does not get assigned), but the second is not:

1) TalksController POST create when not signed in should respond with a 401
     Failure/Error: response.response_code.should == 401
       expected: 401
            got: 302 (using ==)
     # ./spec/controllers/talks_controller_spec.rb:53:in `block (4 levels) in <top (required)>'

I'm not sure exactly what's going on. Is there a way I can test for the actual response code returned to the browser? Or a better way I can test the authorization?


Source: (StackOverflow)