`
bryant513
  • 浏览: 6040 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
最近访客 更多访客>>
社区版块
存档分类
最新评论

后台管理权限控制

 
阅读更多

最近要开始一个新的项目,用ror来实现,把框架搭建好,Let's coding!
我的项目命名规则是,后台管理的的控制器统一用负数形式,前台则是单数,这样的代码看起来比较规范,无二义性。
全局过滤器判断是否需要登陆need_login? 放在application_controller.rb中

class ApplicationController < ActionController::Base
  protect_from_forgery
  before_filter :need_login?

  private
  def need_login?
    controller_name = params[:controller]
    if controller_name.pluralize ==controller_name
      if session[:adminer].blank?
        flash[:notice] = "请先登录"
        redirect_to "/admins"
      end
    else
      if session[:officex].blank?
        flash[:notice] = "请先登录"
        redirect_to "/"
      end
    end
  end
end 

 

 

登陆和退出action放在admins_controller下

def login
    sys_user = SysUser.find_by_name_and_password(:name => params[:name], :password => SysUser.encrypted_pwd(params[:password))
    if sys_user.blank?
        flash[:notice] = "账号或密码错误"
        redirect_to "/admins"
    else 
        session[:adminer] = sys_user
        redirect_to "/admins/admin"
    end
end

def logout
    reset_session
    redirect_to "/admins"
end

 

下午新建了一个Sys_menus的数据表,用来后台菜单的显示,以前是写死的,现在用数据库的方式,就可以自己维护了

sys_menus的字段有action_name,action_url,parent_id,sort

使用方法:在admins_helper.rb中添加两个方法get_permission 和 is_visual

 

#返回当前用户的权限值
def get_permissions
    sys_user = SysUser.find session[:adminer][:id]
    sys_use_permission = []
    sys_user.sys_roles.each do |r|
        role_permission = []
        r.sys_action_permissions.each do |p|
            role_permission << p.permission_value
        end
        sys_user_permission = sys_user_permission + role_permission
    end
    sys_user_permission
end

#判断是否显示,如果是superuser则跳过
def is_visual value
    session[:adminer][:name]=="superuser" or get_permissions.uniq.include?(value)
end

admins_controller.rb

def nav
    @parents = SysMenu.where("parent_id=0").order("sort DESC").all
    @actions = SysMenu.where("parent_id!=0").order("sort DESC").all
    render :layout => false
end

 

nav.rhtml

 

<% @parents.each do |p| %>
<label><%= p.action_name%></label>
<ul>
    <% @actions.each do |a| %>
        <% next if a.parent_id != p.id %>
        <% if is_visual(a.action_url)%><li><a href="<%=a.action_url%>"><%=a.action_name%></a></li>
        <%end%>
    <%end%>
</ul>

  怎么样才能让权限控制更加flexible呢?

在sys_roles_controller.rb中加入refresh_permission

 

#只有superuser才可以调用
def refresh_permission
    if session[:adminer].name != "superuser"
        render :text => "Sorry! You are not allowed."
        return
    end
    SysActionPermission.create_all_permissions
end

 重点就在这里拉,create_all_permissions的实现

 

def self.create_all_permissions
    require "find"
    root = SysActionPermission.find_by_parent_id(0)
    root = SysActionPermission.create({:permission_name=>"根节点",:permissionvalue=>"/",:parent_id=>0,:sort=>100}) if root.blank?
    dir = File.expand_path(Rails.root) + "/app/controllers"
    actions = []
    Find.find("#{dir}/") do |path|
        Find.prune if path =~ /.svn/ #过滤一些目录下不需要的文件
        if File.file?(path) and path.end_with?("_controller.rb") and path.end_with?("admins_controller.rb") 
            parent_name = path.sub(dir,'').sub('_controller.rb','')
            if parent_name == parent_name.pluralize
                parent = SysActionPermission.find_by_permission_value_and_parent_id(parent_name, root.id)
                obj = eval(ActiveSupport::Inflector.camelize(path.sub(dir, '').sub('.rb',''))).new
          #若二级权限已存在则不创建
          parent = SysActionPermission.create(:permission_name => "#{parent_name}", :permission_value => "#{parent_name}", :parent_id => root.id) if parent.blank?
          parent_id = parent.id
          all_public_methods = obj.public_methods(false)
          for action_name in all_public_methods
            #若已存在则不创建
            value = "#{parent_name}/#{action_name}"
            if(SysActionPermission.find_by_permission_value_and_parent_id(value, parent_id).blank?)
              actions << {:permission_name => "#{value}", :permission_value => "#{value}", :parent_id => parent_id}
            end
          end
        end
      end
    end
    SysActionPermission.create(actions.uniq)
    all_has_created_permissions = SysActionPermission.all
    for permissrions in all_has_created_permissions.compact
      next if permissrions.parent_id == 0
      #查看控制器存在与否
      if permissrions.permission_value.count("/") == 1
        if !File.exist?(File.expand_path(Rails.root) + "/app/controllers" + permissrions.permission_value + "_controller.rb")
          ActiveRecord::Base.connection.execute("DELETE FROM sys_action_permissions WHERE parent_id = #{permissrions.id} or id = #{permissrions.id}")
        end
      elsif permissrions.permission_value.count("/") == 2
        controller = permissrions.permission_value.split("/")[1] + "_controller"
        action = permissrions.permission_value.split("/")[2]
        begin
        public_methods = eval(ActiveSupport::Inflector.camelize(controller)).new.public_methods(false)
        if !public_methods.include?(action.to_sym)
          permissrions.destroy
        end
        rescue => e
          p e
        end
      end
    end 
end
 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics