0

如何让超级管理员真正创建用户?我需要策略 CreateusersPolicy 吗?我的代码当前将我带到可以创建用户的页面/表单,但它实际上并没有创建用户。

如果我需要包含更多信息,请告诉我!

配置/路由.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 %>

应用程序/polices/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
4

1 回答 1

1

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

它应该是这样的:

# 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 文档是一个很好的资源来进行所有设置,但它确实需要一些试验和错误。

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

于 2014-10-28T15:18:39.227 回答