Class: PapersPlease::Policy

Inherits:
Object
  • Object
show all
Defined in:
lib/papers_please/policy.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(user) ⇒ Policy



6
7
8
9
10
11
12
# File 'lib/papers_please/policy.rb', line 6

def initialize(user)
  @user          = user
  @roles         = {}
  @cache         = {}

  configure
end

Instance Attribute Details

#rolesObject

Returns the value of attribute roles.



3
4
5
# File 'lib/papers_please/policy.rb', line 3

def roles
  @roles
end

#userObject (readonly)

Returns the value of attribute user.



4
5
6
# File 'lib/papers_please/policy.rb', line 4

def user
  @user
end

Instance Method Details

#add_permissions(keys) ⇒ Object Also known as: permit

Add permissions to the Role



31
32
33
34
35
36
37
38
39
# File 'lib/papers_please/policy.rb', line 31

def add_permissions(keys)
  return unless block_given?

  Array(keys).each do |key|
    raise MissingRole unless roles.key?(key)

    yield roles[key]
  end
end

#add_role(name, predicate = nil, &block) ⇒ Object Also known as: role

Add a role to the Policy

Raises:



19
20
21
22
23
24
25
26
27
# File 'lib/papers_please/policy.rb', line 19

def add_role(name, predicate = nil, &block)
  name = name.to_sym
  raise DuplicateRole if roles.key?(name)

  role = Role.new(name, predicate: predicate, definition: block)
  roles[name] = role

  role
end

#applicable_rolesObject

Fetch roles that apply to the current user



88
89
90
91
92
# File 'lib/papers_please/policy.rb', line 88

def applicable_roles
  @applicable_roles ||= roles.select do |_, role|
    role.applies_to?(user)
  end
end

#authorize!(action, subject) ⇒ Object

Raises:



69
70
71
72
73
# File 'lib/papers_please/policy.rb', line 69

def authorize!(action, subject)
  raise AccessDenied, "Access denied for #{action} on #{subject}" if cannot?(action, subject)

  subject
end

#can?(action, subject = nil) ⇒ Boolean

Look up a stored permission block and call with the current user and subject



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/papers_please/policy.rb', line 44

def can?(action, subject = nil)
  applicable_roles.each do |_, role|
    permission = role.find_permission(action, subject)
    next if permission.nil?

    # Proxy permission check if granted by other
    if permission.granted_by_other?
      # Get proxied subject
      subject = subject.is_a?(Class) ? permission.granting_class : permission.granted_by.call(user, subject)

      # Get proxied permission
      permission = role.find_permission(action, subject)
    end

    # Check permission
    return permission.granted?(user, subject, action) unless permission.nil?
  end

  false
end

#cannot?(*args) ⇒ Boolean



65
66
67
# File 'lib/papers_please/policy.rb', line 65

def cannot?(*args)
  !can?(*args)
end

#configureObject

Raises:

  • (NotImplementedError)


14
15
16
# File 'lib/papers_please/policy.rb', line 14

def configure
  raise NotImplementedError, 'The #configure method of the access policy was not implemented'
end

#scope_for(action, klass) ⇒ Object Also known as: query

Look up a stored scope block and call with the current user and class



77
78
79
80
81
82
83
84
# File 'lib/papers_please/policy.rb', line 77

def scope_for(action, klass)
  applicable_roles.each do |_, role|
    permission = role.find_permission(action, klass)
    return permission.fetch(user, klass, action) unless permission.nil?
  end

  nil
end