Class: Authorize::Role

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/authorize/role.rb

Constant Summary collapse

GRAPH_ID =
Authorize::Graph::DirectedAcyclicGraph.subordinate_key(Authorize::Role, 'graph')
VERTICES_ID_PREFIX =
Authorize::Graph::DirectedAcyclicGraph.subordinate_key(Authorize::Role, 'vertices')

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.const_missing(const) ⇒ Object



18
19
20
21
22
23
24
# File 'lib/authorize/role.rb', line 18

def self.const_missing(const)
  if global_role = scoped(:conditions => {:resource_type => nil, :resource_id => nil}).find_by_relation(const.to_s)
    const_set(const, global_role)
  else
    super
  end
end

.graphObject



26
27
28
29
30
# File 'lib/authorize/role.rb', line 26

def self.graph
  @graph ||= Authorize::Graph::DirectedGraph.load(GRAPH_ID).tap do |g|
    g.vertex_namespace = VERTICES_ID_PREFIX
  end
end

Instance Method Details

#ancestorsObject



101
102
103
104
105
# File 'lib/authorize/role.rb', line 101

def ancestors
  ids = reverse_traverser.map{|v| v.id.slice(/#{VERTICES_ID_PREFIX}::(\d+)/, 1)}
  ids -= [id.to_s]
  self.class.find(ids).to_set
end

#create_vertexObject



32
33
34
# File 'lib/authorize/role.rb', line 32

def create_vertex
  self.class.graph.vertex(id)
end

#descendantsObject



97
98
99
# File 'lib/authorize/role.rb', line 97

def descendants
  roles.delete(self)
end

#destroy_vertexObject



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

def destroy_vertex
  vertex.destroy
end

#inboundObject



107
108
109
110
111
# File 'lib/authorize/role.rb', line 107

def inbound
  ids = []
  self.vertex.inbound_edges.to_a.each{|e| ids << e.from.id.slice(/#{VERTICES_ID_PREFIX}::(\d+)/, 1)}
  self.class.find(ids).to_set
end

Link from this role’s vertex to other’s vertex in the system role graph. This role becomes the parent.



41
42
43
# File 'lib/authorize/role.rb', line 41

def link(other)
  self.class.graph.join(nil, vertex, other.vertex)
end

#may(*args) ⇒ Object

Creates or updates the unique permission for a given resource to have the given modes Example: public.may(:list, :read, widget)



52
53
54
55
56
57
# File 'lib/authorize/role.rb', line 52

def may(*args)
  p = permissions.for(args.pop).find_or_initialize_by_role_id(id) # need a #find_or_initialize_by_already_specified_scope
  p.mask += Authorize::Permission::Mask[*args]
  p.save
  p.mask.complete
end

#may?(*args) ⇒ Boolean

Test if all given modes are permitted for the given resource

Returns:

  • (Boolean)


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

def may?(*args)
  return false unless p = permissions.for(args.pop).first
  mask = Authorize::Permission::Mask[*args].complete
  mask.subset?(p.mask)
end

#may_not(*args) ⇒ Object

Updates or deletes the unique permission for a given resource to not have the given modes Example: public.may_not(:update, widget)



61
62
63
64
65
66
67
# File 'lib/authorize/role.rb', line 61

def may_not(*args)
  p = permissions.for(args.pop).first
  return Authorize::Permission::Mask[] unless p
  p.mask -= Authorize::Permission::Mask[*args].complete
  p.mask.empty? ? p.destroy : p.save
  p.mask.complete
end

#may_not?(*args) ⇒ Boolean

Test if none of the given modes are permitted for the given resource

Returns:

  • (Boolean)


77
78
79
80
81
# File 'lib/authorize/role.rb', line 77

def may_not?(*args)
  return true unless p = permissions.for(args.pop).first
  mask = Authorize::Permission::Mask[*args].complete
  (mask & p.mask).empty?
end

#rolesObject



92
93
94
95
# File 'lib/authorize/role.rb', line 92

def roles
  ids = traverser.map{|v| v.id.slice(/#{VERTICES_ID_PREFIX}::(\d+)/, 1)}
  self.class.find(ids).to_set
end

#to_sObject



83
84
85
# File 'lib/authorize/role.rb', line 83

def to_s
  (name || "%s") % [relation, resource].compact.join(":") rescue "!! INVALID ROLE NAME !!"
end

Unlink this role’s vertex from other’s vertex in the system role graph.



46
47
48
# File 'lib/authorize/role.rb', line 46

def unlink(other)
  self.class.graph.disjoin(vertex, other.vertex)
end

#vertexObject



87
88
89
90
# File 'lib/authorize/role.rb', line 87

def vertex
  raise 'Not possible to dereference vertex for an unpersisted role' unless id
  @vertex ||= self.class.graph.vertex_by_name(id)
end