This base access control class where roles are defined as are authorizations.
# File lib/padrino-admin/access_control.rb, line 38 def initialize @roles, @authorizations, @project_modules = [], [], [] end
Return true if the given account is allowed to see the given path.
@example Hiding a disallowed link from a user.
# File: config/apps.rb # [...] Padrino.mount('Admin').to('/admin') # File: admin/app.rb class Admin < Padrino::Application # [...] register Padrino::Admin::AccessControl # [...] # Goals: # * Admins can manage widgets and accounts. # * Workers can only manage widgets. access_control.roles_for :admin do |role| role.project_module :accounts, '/accounts' role.project_module :widgets, '/widgets' end access_control.roles_for :worker do |role| role.project_module :widgets, '/widgets' end end # File: admin/views/layouts/application.haml # NOTE The un-mounted path is used ('/accounts' instead of '/admin/accounts') - if access_control.allowed?(current_account, '/accounts') # Admins see the "Profile" link, but Workers do not = link_to 'Profile', url(:accounts, :edit, :id => current_account.id)
# File lib/padrino-admin/access_control.rb, line 104 def allowed?(account=nil, path=nil) path = "/" if path.nil? || path.empty? role = account.role.to_sym rescue nil authorizations = @authorizations.find_all { |auth| auth.roles.include?(:any) } allowed_paths = authorizations.map(&:allowed).flatten.uniq denied_paths = authorizations.map(&:denied).flatten.uniq if account denied_paths.clear # explicit authorizations for the role associated with the given account authorizations = @authorizations.find_all { |auth| auth.roles.include?(role) } allowed_paths += authorizations.map(&:allowed).flatten.uniq # other explicit authorizations authorizations = @authorizations.find_all { |auth| !auth.roles.include?(role) && !auth.roles.include?(:any) } denied_paths += authorizations.map(&:allowed).flatten.uniq # remove paths explicitly allowed for other roles denied_paths += authorizations.map(&:denied).flatten.uniq # remove paths explicitly denied to other roles end return true if allowed_paths.any? { |p| path =~ /^#{p}/ } return false if denied_paths.any? { |p| path =~ /^#{p}/ } true end
Return an array of project_modules.
# File lib/padrino-admin/access_control.rb, line 63 def project_modules(account) role = account.role.to_sym rescue :any authorizations = @authorizations.find_all { |auth| auth.roles.include?(role) } authorizations.flat_map(&:project_modules).uniq end
Return an array of roles.
# File lib/padrino-admin/access_control.rb, line 56 def roles @roles.uniq.reject { |r| r == :any } end
We map project modules for a given role or roles.
# File lib/padrino-admin/access_control.rb, line 45 def roles_for(*roles, &block) raise Padrino::Admin::AccessControlError, "Role #{role} must be present and must be a symbol!" if roles.any? { |r| !r.kind_of?(Symbol) } || roles.empty? raise Padrino::Admin::AccessControlError, "You can't merge :any with other roles" if roles.size > 1 && roles.any? { |r| r == :any } @roles += roles @authorizations << Authorization.new(*roles, &block) end