Module: Consent

Defined in:
lib/consent.rb,
lib/consent/dsl.rb,
lib/consent/view.rb,
lib/consent/rspec.rb,
lib/consent/action.rb,
lib/consent/engine.rb,
lib/consent/ability.rb,
lib/consent/subject.rb,
lib/consent/version.rb,
lib/consent/reloader.rb,
lib/consent/subject_coder.rb,
app/models/consent/history.rb,
lib/consent/model_additions.rb,
app/models/consent/permission.rb,
lib/consent/rspec/consent_view.rb,
lib/consent/permission_migration.rb,
lib/consent/rspec/consent_action.rb,
app/models/consent/application_record.rb,
app/models/concerns/consent/authorizable.rb,
lib/generators/consent/permissions_generator.rb

Overview

Consent makes defining permissions easier by providing a clean, concise DSL for authorization so that your ‘Ability` isn’t bloated with all logic.

Defined Under Namespace

Modules: Authorizable, ModelAdditions, PermissionMigration, Rspec, SubjectCoder Classes: Ability, Action, ApplicationRecord, DSL, Engine, History, Permission, PermissionsGenerator, Reloader, Subject, View

Constant Summary collapse

FULL_ACCESS =
%w[1 true].freeze
NO_ACCESS =
:no_access
ViewNotFound =
Class.new(StandardError)
VERSION =
"2.0.0"

Class Method Summary collapse

Class Method Details

.default_viewsHash<Symbol,Consent::View>

Default views available to every permission

i.e.:

Defining a view with no conditions:
Consent.default_views[:all] = Consent::View.new(:all, "All")

Returns:



36
37
38
# File 'lib/consent.rb', line 36

def self.default_views
  @default_views ||= {}
end

.define(key, label, options = {}, &block) ⇒ Object

Defines a subject with the given key, label and options

i.e:

Consent.define :users, "User management" do
  view :department, "Same department only" do |user|
    { department_id: user.department_id }
  end
  action :read, "Can view users"
  action :update, "Can edit existing user", views: :department
end


96
97
98
99
100
101
# File 'lib/consent.rb', line 96

def self.define(key, label, options = {}, &block)
  defaults = options.fetch(:defaults, {})
  subjects << Subject.new(key, label).tap do |subject|
    DSL.build(subject, defaults, &block)
  end
end

.find_action(subject_key, action_key) ⇒ Consent::Action?

Finds an action within a subject context

Returns:



59
60
61
62
63
64
65
# File 'lib/consent.rb', line 59

def self.find_action(subject_key, action_key)
  find_subjects(subject_key)
    .flat_map(&:actions)
    .find do |action|
      action.key.eql?(action_key)
    end
end

.find_subjects(subject_key) ⇒ Array<Consent::Subject>

Finds all subjects defined with the given key

Returns:



50
51
52
53
54
# File 'lib/consent.rb', line 50

def self.find_subjects(subject_key)
  subjects.find_all do |subject|
    subject.key.eql?(subject_key)
  end
end

.find_view(subject_key, action_key, view_key) ⇒ Consent::View?

Finds a view within a subject context

Returns:



70
71
72
73
74
# File 'lib/consent.rb', line 70

def self.find_view(subject_key, action_key, view_key)
  find_action(subject_key, action_key)&.then do |action|
    action.views[view_key] || raise(Consent::ViewNotFound)
  end
end

.load_subjects!(paths) ⇒ Object

Loads all permission (ruby) files from the given directory and using the given mechanism (default: :require)

Parameters:

  • paths (Array<String,#to_s>)

    paths where the ruby files are located

  • mechanism (:require, :load)

    mechanism to load the files



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

def self.load_subjects!(paths)
  permission_files = paths.map { |dir| File.join(dir, "*.rb") }
  Dir[*permission_files].each { |file| Kernel.load(file) }
end

.subjectsArray<Consent::Subject>

Subjects defined in Consent

Returns:



43
44
45
# File 'lib/consent.rb', line 43

def self.subjects
  @subjects ||= []
end