access_control.rb
上传用户:netsea168
上传日期:2022-07-22
资源大小:4652k
文件大小:5k
- # AccessControl, permit to manage, backend, and frontend access.
- # It's based on the LipsiaSoft Admin.
- # You can define on the fly, roles access, for example:
- #
- # Typo::AccessControl.map :require => [ :administrator, :manager, :customer ] do |map|
- # # Shared Permission
- # map.permission "backend/base"
- # # Module Permission
- # map.project_module :accounts, "backend/accounts" do |project|
- # project.menu :list, { :action => :index }, :class => "icon-no-group"
- # project.menu :new, { :action => :new }, :class => "icon-new"
- # end
- #
- # end
- #
- # Typo::AccessControl.map :require => :customer do |map|
- # # Shared Permission
- # map.permission "frontend/cart"
- # # Module Permission
- # map.project_module :store, "frontend/store" do |map|
- # map.menu :add, { :cart => :add }, :class => "icon-no-group"
- # map.menu :list, { :cart => :list }, :class => "icon-no-group"
- # end
- # end
- #
- # So the when you do:
- #
- # Typo::AccessControl.roles
- # # => [:administrator, :manager, :customer]
- #
- # Typo::AccessControl.project_modules(:customer)
- # # => [#<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={}>]>]
- #
- # Typo::AccessControl.allowed_controllers(:customer)
- # => ["backend/base", "backend/accounts", "frontend/cart", "frontend/store"]
- #
- # If in your controller there is *login_required* our Authenticated System verify the allowed_controllers for the account role (Ex: :customer),
- # if not satisfed you will be redirected to login page.
- #
- # An account have two columns, role, that is a string, and project_modules, that is an array (with serialize)
- #
- # For example, whe can decide that an Account with role :customers can see only, the module project :store.
- module AccessControl
- class << self
- def map(role)
- @mappers ||= []
- @roles ||= []
- mapper = Mapper.new(role)
- yield mapper
- @mappers << mapper
- @roles.concat(mapper.roles)
- end
-
- def project_modules(role)
- project_modules = []
- mappers(role).each { |m| project_modules.concat(m.project_modules) }
- return project_modules.uniq.compact
- end
-
- def project_module(role, name)
- project_modules(role).find { |p| p.name == name }
- end
-
- def roles
- return @roles.uniq.compact
- end
-
- def human_roles
- return roles.collect(&:to_s).collect(&:humanize)
- end
-
- def allowed_controllers(role, project_modules)
- controllers = []
- mappers(role).each { |m| controllers.concat(m.controllers) }
- project_modules.each { |m| controllers.concat(project_module(role, m).controllers) if project_module(role, m) }
- return controllers.uniq.compact
- end
-
- private
- def mappers(role)
- @mappers.select { |m| m.roles.include?(role.to_s.downcase.to_sym) }
- end
- end
-
- class Mapper
- attr_reader :project_modules, :roles
-
- def initialize(hash)
- @roles = hash[:require].is_a?(Array) ? hash[:require].collect { |r| r.to_s.downcase.to_sym } : [hash[:require].to_s.downcase.to_sym]
- @project_modules = []
- @controllers = []
- end
-
- def project_module(name, controller = nil)
- project_module = ProjectModule.new(name, controller)
- yield project_module
- @project_modules << project_module
- end
-
- def permission(controller)
- @controllers << controller
- end
-
- def controllers
- return @controllers.uniq.compact
- end
- end
-
- class ProjectModule
- attr_reader :name, :menus, :submenus, :controllers
-
- def initialize(name, controller=nil)
- @name = name
- @controllers, @menus, @submenus = [], [], []
- @controllers << controller
- end
-
- def menu(name, url, options={})
- if url.is_a?(Hash)
- url[:controller].nil? ? url[:controller] = @controllers.first : @controllers << url[:controller]
- end
- @menus << Menu.new(name, url, options)
- end
-
- def submenu(name, url, options={})
- if url.is_a?(Hash)
- url[:controller].nil? ? url[:controller] = @controllers.first : @controllers << url[:controller]
- end
- @submenus << Menu.new(name, url, options)
- end
-
- def human_name
- return @name.to_s.humanize
- end
-
- def uid
- @name.to_s.downcase.gsub(/[^a-z0-9]+/, '').gsub(/-+$/, '').gsub(/^-+$/, '')
- end
- end
-
- class Menu
- attr_reader :name, :options, :url
-
- def initialize(name, url, options)
- @name = name
- @options = options
- @url = url
- end
-
- def human_name
- return @name.to_s.humanize
- end
-
- def uid
- @name.to_s.downcase.gsub(/[^a-z0-9]+/, '').gsub(/-+$/, '').gsub(/^-+$/, '')
- end
- end
- end