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

Returns a new instance of 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

Returns:

  • (Boolean)


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

Returns:

  • (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