Class: Padrino::Admin::AccessControl::Base

Inherits:
Object
  • Object
show all
Defined in:
padrino-admin/lib/padrino-admin/access_control.rb

Overview

This base access control class where roles are defined as are authorizations.

Instance Method Summary collapse

Constructor Details

#initializeBase

Returns a new instance of Base



38
39
40
# File 'padrino-admin/lib/padrino-admin/access_control.rb', line 38

def initialize
  @roles, @authorizations, @project_modules = [], [], []
end

Instance Method Details

#allowed?(account = nil, path = nil) ⇒ Boolean

Return true if the given account is allowed to see the given path.

Examples:

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)

Returns:

  • (Boolean)


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'padrino-admin/lib/padrino-admin/access_control.rb', line 104

def allowed?(=nil, path=nil)
  path = "/" if path.nil? || path.empty?
  role = .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 
    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

#project_modules(account) ⇒ Object

Return an array of project_modules.



63
64
65
66
67
# File 'padrino-admin/lib/padrino-admin/access_control.rb', line 63

def project_modules()
  role = .role.to_sym rescue :any
  authorizations = @authorizations.find_all { |auth| auth.roles.include?(role) }
  authorizations.flat_map(&:project_modules).uniq
end

#rolesObject

Return an array of roles.



56
57
58
# File 'padrino-admin/lib/padrino-admin/access_control.rb', line 56

def roles
  @roles.uniq.reject { |r| r == :any }
end

#roles_for(*roles, &block) ⇒ Object

We map project modules for a given role or roles.



45
46
47
48
49
50
51
# File 'padrino-admin/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