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



42
43
44
# File 'padrino-admin/lib/padrino-admin/access_control.rb', line 42

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)


108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'padrino-admin/lib/padrino-admin/access_control.rb', line 108

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



67
68
69
70
71
# File 'padrino-admin/lib/padrino-admin/access_control.rb', line 67

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.



60
61
62
# File 'padrino-admin/lib/padrino-admin/access_control.rb', line 60

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

#roles_for(*roles, &block) ⇒ Object

We map project modules for a given role or roles.



49
50
51
52
53
54
55
# File 'padrino-admin/lib/padrino-admin/access_control.rb', line 49

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