204 lines
6.7 KiB
Ruby
204 lines
6.7 KiB
Ruby
class ActiveRecord::Base
|
|
|
|
def add_role_to model, role
|
|
return false unless ActiveRecord::Base.relation_acter? model.class and ActiveRecord::Base.relation_target? self.class
|
|
return false unless ['', model.class.to_s].include? role.to
|
|
rel = Relation.by_object(model).by_target(self).first ||
|
|
Relation.new(:object_id => model.id, :object_type => model.class.to_s,
|
|
:target_id => self.id, :target_type => self.class.to_s)
|
|
rel.roles << role unless rel.roles.include? role
|
|
rel.save
|
|
end
|
|
|
|
def add_role_on model, role
|
|
return false unless ActiveRecord::Base.relation_target? model.class and ActiveRecord::Base.relation_acter? self.class
|
|
return false unless ['', self.class.to_s].include? role.to
|
|
rel = Relation.by_object(self).by_target(model).first
|
|
rel = Relation.new(:object_id => self.id, :object_type => self.class.to_s,
|
|
:target_id => model.id, :target_type => model.class.to_s) if rel.nil?
|
|
rel.roles << role unless rel.roles.include? role
|
|
rel.save
|
|
end
|
|
|
|
def add_roles_to model, roles
|
|
return false unless ActiveRecord::Base.relation_acter? model.class and ActiveRecord::Base.relation_target? self.class
|
|
roles = roles.select{|role| ['', model.class.to_s].include? role.to}
|
|
return false if roles.empty?
|
|
rel = Relation.by_object(model).by_target(self).first ||
|
|
Relation.new(:object_id => model.id, :object_type => model.class.to_s,
|
|
:target_id => self.id, :target_type => self.class.to_s)
|
|
rel.roles.concat(roles - rel.roles) if roles
|
|
rel.save
|
|
end
|
|
|
|
def add_roles_on model, roles
|
|
return false unless ActiveRecord::Base.relation_target? model.class and ActiveRecord::Base.relation_acter? self.class
|
|
roles = roles.select{|role| ['', self.class.to_s].include? role.to}
|
|
return false if roles.empty?
|
|
rel = Relation.by_object(self).by_target(model).first ||
|
|
Relation.new(:object_id => self.id, :object_type => self.class.to_s,
|
|
:target_id => model.id, :target_type => model.class.to_s)
|
|
rel.roles.concat(roles - rel.roles) if roles
|
|
rel.save
|
|
end
|
|
|
|
def remove_roles_from_acter acter, roles
|
|
return false unless ActiveRecord::Base.relation_acter? acter.class
|
|
return false unless ActiveRecord::Base.relation_target? self.class
|
|
|
|
rel = Relation.by_object(self).by_target(model).first
|
|
return false unless rel
|
|
rel.roles = rel.roles - roles
|
|
if rel.roles.empty?
|
|
rel.destroy
|
|
else
|
|
rel.save
|
|
end
|
|
end
|
|
|
|
def roles_to object
|
|
return [] unless ActiveRecord::Base.relation_acter? self.class
|
|
object = object.downcase.to_sym if object.is_a? String
|
|
possible = [self]
|
|
if @@relationable[self.class.to_s][:inherits]
|
|
@@relationable[self.class.to_s][:inherits].each do |n|
|
|
possible.concat method(n).call
|
|
end
|
|
end
|
|
possible.flatten
|
|
if object.is_a? Symbol and object == :system
|
|
return possible.map{|obj| obj.global_role}.uniq
|
|
else
|
|
r = possible.inject([]) do |arr, mod|
|
|
rels = Relation.by_object(mod).by_target(object)
|
|
arr.concat rels.map{|rel| rel.roles} if rels.size > 0
|
|
arr << mod.global_role
|
|
arr
|
|
end
|
|
return r.flatten.uniq
|
|
end
|
|
end
|
|
|
|
def can_perform? controller, action, target = :system
|
|
all_rights = rights_to target
|
|
needed_right = right_to controller, action
|
|
return all_rights.include? needed_right
|
|
end
|
|
|
|
def right_to controller, action
|
|
Right.where(:controller => controller, :action => action).first
|
|
end
|
|
|
|
def rights_to object
|
|
r = roles_to(object).compact.uniq
|
|
return [] if r.nil?
|
|
r.map {|role| role.rights}.flatten.compact.uniq
|
|
end
|
|
|
|
protected
|
|
def add_default_role
|
|
return false unless ActiveRecord::Base.relation_acter? self.class
|
|
role = Role.by_acter(self.class).by_target(:system).default.first ||
|
|
Role.by_acter(:all).by_target(:system).default.first
|
|
self.global_role = role
|
|
end
|
|
|
|
def add_owner owner
|
|
return false unless ActiveRecord::Base.relation_acter? owner.class
|
|
return false unless ActiveRecord::Base.relation_target? self.class
|
|
roles = Role.by_acter(owner.class).by_target(self.class).owner_default +
|
|
Role.by_acter(:all).by_target(self.class).owner_default
|
|
add_roles_to owner, roles
|
|
end
|
|
|
|
def remove_owner owner
|
|
return false unless ActiveRecord::Base.relation_acter? owner.class
|
|
return false unless ActiveRecord::Base.relation_target? self.class
|
|
roles = Role.by_acter(owner.class).by_target(self.class).owner_default +
|
|
Role.by_acter(:all).by_target(self.class).owner_default
|
|
remove_roles_form_acter owner, roles
|
|
end
|
|
|
|
class << self
|
|
|
|
def visible_to object
|
|
return scoped unless (public_instance_methods + column_names).include? 'visibility'
|
|
rs = (object.roles_to :system).compact
|
|
vis = rs.inject({}) do |h, r|
|
|
unless r.can_see.nil?
|
|
h.merge!(r.can_see) {|k, old, new| old.concat(new).uniq}
|
|
end
|
|
h
|
|
end
|
|
vis = vis[self.name]
|
|
return where('1=2') if !vis or vis.empty?
|
|
if vis == self::VISIBILITIES
|
|
return scoped # all
|
|
else
|
|
return by_visibilities(vis)
|
|
end
|
|
end
|
|
|
|
def inherit_rights_from arg
|
|
if relation_acters.include? self
|
|
@@relationable[self.name] ||= {}
|
|
@@relationable[self.name][:inherits] ||= []
|
|
|
|
if arg.is_a? Array
|
|
@@relationable[self.name][:inherits].concat(arg)
|
|
else
|
|
@@relationable[self.name][:inherits] << arg
|
|
end
|
|
end
|
|
end
|
|
|
|
def relationable?
|
|
return true if @@relationable[self.name] and @@relationable[self.name].size > 0
|
|
false
|
|
end
|
|
|
|
def relation_acter? model
|
|
relation_acters.include? model
|
|
end
|
|
|
|
def relation_target? model
|
|
relation_targets.include? model
|
|
end
|
|
|
|
def relation_acters
|
|
load_all unless @@all_models_loaded
|
|
return Hash[@@relationable.select {|(k,v)| v[:as].include? :object}].keys.map{|m| m.constantize}
|
|
end
|
|
|
|
def relation_targets
|
|
load_all unless @@all_models_loaded
|
|
return Hash[@@relationable.select {|(k,v)| v[:as].include? :target}].keys.map{|m| m.constantize}
|
|
end
|
|
|
|
def load_all
|
|
Dir["app/models/**/*.rb"].each do |fn|
|
|
require File.expand_path(fn)
|
|
end
|
|
@@all_modles_loaded = true
|
|
end
|
|
|
|
protected
|
|
|
|
@@relationable = {}
|
|
@@all_models_loaded = false
|
|
|
|
def relationable(arg)
|
|
@@relationable[self.name] ||= {}
|
|
@@relationable[self.name][:as] ||= []
|
|
|
|
if arg[:as] and [:object, :target].include? arg[:as]
|
|
@@relationable[self.name][:as] << arg[:as]
|
|
else
|
|
@@relationable[self.name][:as] << :target
|
|
end
|
|
@@relationable[self.name][:as].uniq!
|
|
end
|
|
end
|
|
|
|
end
|