Я использую Devise для аутентификации, Rolify для управления ролями и CanCan 2.0 для авторизации.
Я пытаюсь разрешить роли :admin изменять роли пользователя, но запрещаю доступ всем другим пользователям.
Вот что я пробовал и не работает:
#ability.rb
class Ability
include CanCan::Ability
def initialize(user)
if user.has_role? :admin
can :access, :all
elsif user.has_role? :moderator
can [:index, :read, :update, :destroy], :users, :user_id => user.id
cannot :access, :users, [:role_ids]
end
end
#application_controller.rb
...
rescue_from CanCan::Unauthorized do |exception|
redirect_to root_url, :alert => exception.message
end
Я намеренно оставил ассоциацию в своей пользовательской форме:
#_form.html.erb
<%= simple_form_for @user do |f| %>
<%= f.association :roles, as: :check_boxes %>
<%#= f.association :roles, as: :check_boxes if can? :update, @user, :roles %>
<%= f.button :submit %>
<% end %>
контроллер
#users_controller.rb
class UsersController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource
def index
@users = User.accessible_by(current_ability)
end
def new
@user = User.new
end
def create
@user = User.new(params[:user])
end
def show
@user = User.find(params[:id])
end
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
@user.update_without_password(params[:user])
if successfully_updated
redirect_to @user
else
render :action => "edit"
end
end
end
и модель:
#user.rb
class User < ActiveRecord::Base
rolify
attr_accessible :role_ids
...
Теперь, если пользователь с ролью :moderator попытается изменить роли другого пользователя (или свои собственные), произойдет следующее:
- Выдается исключение CanCan::Unauthorized, и пользователь перенаправляется на root_url.
- Роли изменены для пользователя
Я смущен. Если происходит исключение, почему изменения все еще вносятся? Я, наверное, что-то очень неправильно делаю :)
Я попытался манипулировать параметрами запроса в зависимости от роли пользователя в users_controller.rb. Если я помещу оператор журнала сразу после обновления def, вот мой вывод:
2013-04-24 12:42:21 [4161] DEBUG (0.1ms) BEGIN
2013-04-24 12:42:21 [4161] DEBUG (0.3ms) INSERT INTO "users_roles" ("user_id", "role_id") VALUES (5, 1)
2013-04-24 12:42:21 [4161] DEBUG (0.4ms) COMMIT
2013-04-24 12:42:21 [4161] DEBUG User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", "5"]]
2013-04-24 12:42:21 [4161] DEBUG {"username"=>"Blabla", "email"=>"[email protected]", "password"=>"", "password_confirmation"=>"", "approved"=>"1", "role_ids"=>["1", "2", ""]}
Я, должно быть, что-то упускаю из виду...
if can? :update, @user, :roles
правильно показывает/скрывает флажки? если да, то я думаю, что канкан сделал свое дело. Действиеupdate
может потребоваться разделить наupdate
иadmin_update
, при этом 2-е действие может касаться ролей. - person tw airball   schedule 22.04.2013cannot :access, :users, [:role_ids]
? Похоже, либо неправильный синтаксис, либо я что-то упускаю. - person zkcro   schedule 24.04.2013