Devise-Pundit:为Superadmin创建一个用于创建用户的页面,但它实际上并不是在创建用户

时间:2014-10-25 20:34:13

标签: devise pundit

如何启用Superadmin实际创建用户?我是否需要策略CreateusersPolicy?我的代码目前将我带到我可以创建用户的页面/表单,但它实际上并没有创建用户。

如果我需要提供更多信息,请与我们联系!

配置/ routes.rb中

Rails.application.routes.draw do
  devise_for :users
  resources :users, except: :create
  root "pages#home"

  get "index" => "users#index"
  get 'create_user' => 'users#create', as: :create_user 

控制器/ application_controller.rb

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  include Pundit
  protect_from_forgery 

  def authorize_superadmin
    redirect_to root_path, alert: 'Access Denied' unless current_user.superadmin?
  end
end

我也不知道在创建部分放置什么。

控制器/ users_controller.rb

class UsersController < ApplicationController
  before_filter :authenticate_user!
  #before_filter :authorize_superadmin, except [:show]
  #after_action :verify_authorized


  def create
    # user create code (can't get here if not admin)
  end

  def index
    @users = User.all
    authorize User
  end

  def show
   @user = User.find(params[:id])
   authorize @user
  end

  def update
    @user = User.find(params[:id])
    authorize @user
    if @user.update_attributes(secure_params)
      redirect_to users_path, :notice => "User updated."
    else
      redirect_to users_path, :alert => "Unable to update user."
    end
  end

  def destroy
    user = User.find(params[:id])
    authorize user
    user.destroy
    redirect_to users_path, :notice => "User deleted."
  end

  private

  def secure_params
    params.require(:user).permit(:role)
  end

end

视图/用户/ create.html.erb

<%= form_for User.new, url: create_user_path do |f| %>

  <div><%= f.label :first_name %><br />
  <%= f.text_field :first_name, autofocus: true %></div>

  <div><%= f.label :last_name %><br />
  <%= f.text_field :last_name, autofocus: true %></div>

  <div><%= f.label :email %><br />
  <%= f.email_field :email, autofocus: true %></div>

  <div><%= f.label :phone_number%><br />
  <%= f.phone_field :phone_number, autofocus: true %></div>

  <div><%= f.label :street %><br />
  <%= f.text_field :street, autofocus: true %></div>

  <div><%= f.label :city %><br />
  <%= f.text_field :city, autofocus: true %></div>

  <div><%= f.label :state %><br />
  <%= f.text_field :state, autofocus: true %></div>

  <div><%= f.label :zip %><br />
  <%= f.text_field :zip, autofocus: true %></div>

  <div><%= f.label :password %> <% if @validatable %><i>(<%= @minimum_password_length %> characters minimum)</i><% end %><br />
    <%= f.password_field :password, autocomplete: "off" %></div>

  <div><%= f.label :password_confirmation %><br />
  <%= f.password_field :password_confirmation, autocomplete: "off" %></div>

  <div><%= f.submit "Create" %></div>

<% end %>

应用程序/策略/ user_policy.rb

class UserPolicy
  attr_reader :current_user, :model

  def initialize(current_user, model)
    @current_user = current_user
    @user = model
  end

  def index?
    @current_user.superadmin?
  end

  def show?
    @current_user.superadmin? or @current_user == @user
  end

 def update?
    @current_user.superadmin?
 end

 def destroy?
   return false if @current_user == @user
    @current_user.superadmin?
 end

 def permitted_attributes
    if @current_user.superadmin?
      [:role]
    else
      [:name, :email]
    end
  end

end

1 个答案:

答案 0 :(得分:1)

您在UserPolicy文件中没有create?方法,因此您实际上并未授权任何内容(据我所知)。

它应该是这样的:

# app/policies/user_policy.rb
def create?
  @current_user.superadmin?
end

# app/controllers/users_controller.rb
def create
  authorize User
  # rest of method to create user
end

此外,您不需要(或希望IMO)使用authorize_superadmin方法(您在控制器中注释了before_filter,因此您不会调用它),因为a)您将在操作中调用authorize方法,这将是多余的; b)您希望将授权逻辑保留在一个位置:UserPolicy类。如果授权失败,它将引发异常,并且不会调用其余的动作。

Pundit documentation是获取所有设置的绝佳资源,但它确实需要一些试验和错误。

我还强烈建议您创建一个ApplicationPolicy,继承所有特定于模型的授权,以便您可以捕获可能未定义的内容。这一切都在文档中。