Class: Consent::Ability

Inherits:
Object
  • Object
show all
Includes:
CanCan::Ability
Defined in:
lib/consent/ability.rb

Overview

Defines a CanCan(Can)::Ability class based on Consent::Permissions

Instance Method Summary collapse

Constructor Details

#initialize(*context, permissions: nil, super_user: false, apply_defaults: true) ⇒ Ability

Initialize a Consent::Ability consenting all the given permissions.

When super_user is set to true, it grants ‘:manage :all`, which is understood by CanCan as a keyword to allow everything with no restrictions.

If apply_defaults is set to true, Consent::Ability will grant the default views defined in the permissions.

I.e.:

Consent.define Project, 'Projects' do
  view :department, "User's department only" do |user|
    { department_id: user.id }
  end
  view :self, "User's own projects" do |user|
    { user_id: user.id }
  end

  action :close, views: %i[department self], default_view: :self
end

Consent::Ability.new(user, permissions: user&.permissions,
                           super_user: user&.super_user?,
                           apply_defaults: user.present?)

Parameters:

  • *context (*)

    the view context, usually the user and some additional information

  • permissions (Array<Consent::Permission>) (defaults to: nil)

    the list of permissions to grant

  • super_user (Boolean) (defaults to: false)

    whether Consent should grant :manage :all

  • apply_defaults (Boolean) (defaults to: true)

    whether Consent should grant default views



41
42
43
44
45
46
47
48
49
50
# File 'lib/consent/ability.rb', line 41

def initialize(*context, permissions: nil, super_user: false, apply_defaults: true)
  @context = *context

  apply_defaults! if apply_defaults
  can :manage, :all if super_user

  permissions&.each do |permission|
    consent(**permission.slice(:subject, :action, :view).symbolize_keys)
  end
end

Instance Method Details

#can?(action_or_pair, subject = nil, *args) ⇒ Boolean

Check if the user has permission to perform a given action on an object.

can? :destroy, @project

You can also pass the class instead of an instance (if you don’t have one handy).

can? :create, Project

You can also check with string form of the permission:

can? "project/create"

For more info, check the documentation of [CanCan::Ability]

Returns:

  • (Boolean)


111
112
113
114
# File 'lib/consent/ability.rb', line 111

def can?(action_or_pair, subject = nil, *args)
  action, subject = extract_action_subject(action_or_pair, subject)
  super action, subject, *args
end

Consents a subject/action/view to the ability

See Also:



80
81
82
83
84
# File 'lib/consent/ability.rb', line 80

def consent(**kwargs)
  consent!(**kwargs)
rescue Consent::ViewNotFound
  nil
end

#consent!(subject: nil, action: nil, view: nil) ⇒ Object

Consents a subject/action/view to the ability

‘consent!` will add a `can` permission to the ability based on the view rules defined in the Consent definitions.

Parameters:

  • subject (Class, Symbol) (defaults to: nil)

    the target subject of the action

  • action (Symbol) (defaults to: nil)

    the action being granted on the subject

  • view (Symbol, nil) (defaults to: nil)

    the conditions/rules on which the action is granted



62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/consent/ability.rb', line 62

def consent!(subject: nil, action: nil, view: nil)
  view = case view
         when Consent::View
           view
         when Symbol
           Consent.find_view(subject, action, view)
         end

  can(
    action, subject,
    view&.conditions(*@context), &view&.object_conditions(*@context)
  )
end

#relation_model_adapter(model_class, action_or_pair, subject, relation) ⇒ Object



117
118
119
120
121
122
# File 'lib/consent/ability.rb', line 117

def relation_model_adapter(model_class, action_or_pair, subject, relation)
  action, subject = extract_action_subject(action_or_pair, subject)
  ::CanCan::ModelAdapters::AbstractAdapter
    .adapter_class(model_class)
    .new(model_class, relation_rules(model_class, action, subject, relation))
end

#to_h(permissions = nil) ⇒ Hash<String,Boolean>

Returns a hash where the keys are the given permissions, and the values are either true or false, representing their ability to perform the given permision

Parameters:

  • permissions (Array<String>, String, nil) (defaults to: nil)

    an array of the requested permissions

Returns:

  • (Hash<String,Boolean>)

    the hash with the results



92
93
94
95
96
# File 'lib/consent/ability.rb', line 92

def to_h(permissions = nil)
  Array(permissions).reduce({}) do |result, permission|
    result.merge permission => can?(permission)
  end
end