access_control.rb
上传用户:netsea168
上传日期:2022-07-22
资源大小:4652k
文件大小:5k
源码类别:

Ajax

开发平台:

Others

  1.   # AccessControl, permit to manage, backend, and frontend access.
  2.   # It's based on the LipsiaSoft Admin.
  3.   # You can define on the fly, roles access, for example:
  4.   # 
  5.   #   Typo::AccessControl.map :require => [ :administrator, :manager, :customer ]  do |map|
  6.   #     # Shared Permission
  7.   #     map.permission "backend/base"
  8.   #     # Module Permission
  9.   #     map.project_module :accounts, "backend/accounts" do |project|
  10.   #       project.menu :list, { :action => :index }, :class => "icon-no-group"
  11.   #       project.menu :new,  { :action => :new }, :class => "icon-new"
  12.   #     end
  13.   # 
  14.   #   end
  15.   # 
  16.   #   Typo::AccessControl.map :require => :customer do |map|
  17.   #     # Shared Permission
  18.   #     map.permission "frontend/cart"
  19.   #     # Module Permission
  20.   #     map.project_module :store, "frontend/store" do |map|
  21.   #       map.menu :add, { :cart => :add }, :class => "icon-no-group"
  22.   #       map.menu :list,  { :cart => :list }, :class => "icon-no-group"
  23.   #     end  
  24.   #   end                                                                    
  25.   # 
  26.   # So the when you do:
  27.   #
  28.   #   Typo::AccessControl.roles
  29.   #   # => [:administrator, :manager, :customer]
  30.   #   
  31.   #   Typo::AccessControl.project_modules(:customer)
  32.   #   # => [#<Typo::AccessControl::ProjectModule:0x254a9c8 @controller="backend/accounts", @name=:accounts, @menus=[#<Typo::AccessControl::Menu:0x254a928 @url={:action=>:index}, @name=:list, @options={:class=>"icon-no-group"}>, #<Typo::AccessControl::Menu:0x254a8d8 @url={:action=>:new}, @name=:new, @options={:class=>"icon-new"}>]>, #<Typo::AccessControl::ProjectModule:0x254a84c @controller="frontend/store", @name=:store, @menus=[#<Typo::AccessControl::Menu:0x254a7d4 @url={:cart=>:add}, @name=:add, @options={}>, #<Typo::AccessControl::Menu:0x254a798 @url={:cart=>:list}, @name=:list, @options={}>]>]
  33.   #
  34.   #   Typo::AccessControl.allowed_controllers(:customer)
  35.   #   => ["backend/base", "backend/accounts", "frontend/cart", "frontend/store"]
  36.   #  
  37.   # If in your controller there is *login_required* our Authenticated System verify the allowed_controllers for the account role (Ex: :customer),
  38.   # if not satisfed you will be redirected to login page.
  39.   #
  40.   # An account have two columns, role, that is a string, and project_modules, that is an array (with serialize)
  41.   # 
  42.   # For example, whe can decide that an Account with role :customers can see only, the module project :store.  
  43. module AccessControl
  44.   class << self
  45.     def map(role)
  46.       @mappers ||= []
  47.       @roles ||= []
  48.       mapper = Mapper.new(role)
  49.       yield mapper
  50.       @mappers << mapper
  51.       @roles.concat(mapper.roles)
  52.     end
  53.     
  54.     def project_modules(role)
  55.       project_modules = []
  56.       mappers(role).each { |m| project_modules.concat(m.project_modules) }  
  57.       return project_modules.uniq.compact
  58.     end
  59.     
  60.     def project_module(role, name)
  61.       project_modules(role).find { |p| p.name == name }
  62.     end
  63.   
  64.     def roles
  65.       return @roles.uniq.compact
  66.     end
  67.     
  68.     def human_roles
  69.       return roles.collect(&:to_s).collect(&:humanize)
  70.     end
  71.     
  72.     def allowed_controllers(role, project_modules)
  73.       controllers = []
  74.       mappers(role).each { |m| controllers.concat(m.controllers) }
  75.       project_modules.each { |m| controllers.concat(project_module(role, m).controllers) if project_module(role, m) }
  76.       return controllers.uniq.compact
  77.     end
  78.     
  79.   private
  80.     def mappers(role)
  81.       @mappers.select { |m| m.roles.include?(role.to_s.downcase.to_sym) }
  82.     end
  83.   end
  84.   
  85.   class Mapper
  86.     attr_reader :project_modules, :roles
  87.     
  88.     def initialize(hash)
  89.       @roles = hash[:require].is_a?(Array) ? hash[:require].collect { |r| r.to_s.downcase.to_sym } : [hash[:require].to_s.downcase.to_sym]
  90.       @project_modules = []
  91.       @controllers = []
  92.     end
  93.     
  94.     def project_module(name, controller = nil)
  95.       project_module = ProjectModule.new(name, controller)
  96.       yield project_module
  97.       @project_modules << project_module
  98.     end
  99.     
  100.     def permission(controller)
  101.       @controllers << controller
  102.     end
  103.     
  104.     def controllers
  105.       return @controllers.uniq.compact
  106.     end
  107.   end
  108.   
  109.   class ProjectModule
  110.     attr_reader :name, :menus, :submenus, :controllers
  111.     
  112.     def initialize(name, controller=nil)
  113.       @name = name
  114.       @controllers, @menus, @submenus = [], [], []
  115.       @controllers << controller
  116.     end
  117.     
  118.     def menu(name, url, options={})
  119.       if url.is_a?(Hash) 
  120.         url[:controller].nil? ? url[:controller] = @controllers.first : @controllers << url[:controller]
  121.       end
  122.       @menus << Menu.new(name, url, options)
  123.     end
  124.     
  125.     def submenu(name, url, options={})
  126.       if url.is_a?(Hash) 
  127.         url[:controller].nil? ? url[:controller] = @controllers.first : @controllers << url[:controller]
  128.       end
  129.       @submenus << Menu.new(name, url, options)
  130.     end
  131.     
  132.     def human_name
  133.       return @name.to_s.humanize
  134.     end
  135.     
  136.     def uid
  137.       @name.to_s.downcase.gsub(/[^a-z0-9]+/, '').gsub(/-+$/, '').gsub(/^-+$/, '')
  138.     end
  139.   end
  140.   
  141.   class Menu
  142.     attr_reader :name, :options, :url
  143.     
  144.     def initialize(name, url, options)
  145.       @name = name
  146.       @options = options
  147.       @url = url
  148.     end
  149.     
  150.     def human_name
  151.       return @name.to_s.humanize
  152.     end
  153.     
  154.     def uid
  155.       @name.to_s.downcase.gsub(/[^a-z0-9]+/, '').gsub(/-+$/, '').gsub(/^-+$/, '')
  156.     end
  157.   end
  158. end