end
def index
+ uuid_list = [current_user.uuid, *current_user.groups_i_can(:read)]
+ sanitized_uuid_list = uuid_list.
+ collect { |uuid| model_class.sanitize(uuid) }.join(', ')
@objects ||= model_class.
- joins("LEFT JOIN links permissions ON permissions.head_uuid=#{table_name}.owner AND permissions.tail_uuid=#{model_class.sanitize current_user.uuid} AND permissions.link_class='permission'").
- where("?=? OR #{table_name}.owner=? OR #{table_name}.uuid=? OR permissions.head_uuid IS NOT NULL",
+ joins("LEFT JOIN links permissions ON permissions.head_uuid=#{table_name}.owner AND permissions.tail_uuid in (#{sanitized_uuid_list}) AND permissions.link_class='permission'").
+ where("?=? OR #{table_name}.owner in (?) OR #{table_name}.uuid=? OR permissions.head_uuid IS NOT NULL",
true, current_user.is_admin,
- current_user.uuid, current_user.uuid)
+ uuid_list,
+ current_user.uuid)
if params[:where]
where = params[:where]
where = Oj.load(where) if where.is_a?(String)
module ApplicationHelper
-
- ALL_PERMISSIONS = {read: true, write: true, manage: true}
-
def current_user
controller.current_user
end
-
- def invalidate_permissions_cache
- Rails.cache.delete_matched(/^groups_for_user_/)
- end
-
- def groups_i_can(verb)
- current_group_permissions.select { |uuid, mask| mask[verb] }.keys
- end
-
- def current_group_permissions
- return {} unless current_user
- Rails.cache.fetch "groups_for_user_#{current_user.uuid}" do
- permissions_from = {}
- todo = {current_user.uuid => true}
- done = {}
- while !todo.empty?
- lookup_uuids = todo.keys
- lookup_uuids.each do |uuid| done[uuid] = true end
- todo = {}
- Link.where('tail_uuid in (?) and link_class = ? and head_kind = ?',
- lookup_uuids,
- 'permission',
- 'orvos#group').each do |link|
- unless done.has_key? link.head_uuid
- todo[link.head_uuid] = true
- end
- link_permissions = {}
- case link.name
- when 'can_read'
- link_permissions = {read:true}
- when 'can_write'
- link_permissions = {read:true,write:true}
- when 'can_manage'
- link_permissions = ALL_PERMISSIONS
- end
- permissions_from[link.tail_uuid] ||= {}
- permissions_from[link.tail_uuid][link.head_uuid] ||= {}
- link_permissions.each do |k,v|
- permissions_from[link.tail_uuid][link.head_uuid][k] ||= v
- end
- end
- end
- search_permissions(current_user.uuid, permissions_from)
- end
- end
-
- protected
-
- def search_permissions(start, graph, merged={}, upstream_mask=nil, upstream_path={})
- nextpaths = graph[start]
- return merged if !nextpaths
- return merged if upstream_path.has_key? start
- upstream_path[start] = true
- upstream_mask ||= ALL_PERMISSIONS
- nextpaths.each do |head, mask|
- merged[head] ||= {}
- mask.each do |k,v|
- merged[head][k] ||= v if upstream_mask[k]
- end
- search_permissions(head, graph, merged, upstream_mask.select { |k,v| v && merged[head][k] }, upstream_path)
- end
- upstream_path.delete start
- merged
- end
-
end
# permissions for head_uuid and tail_uuid, and invalidate the
# cache for only those users. (This would require a browseable
# cache.)
- invalidate_permissions_cache
+ User.invalidate_permissions_cache
end
end
end
t.add :prefs
end
+ ALL_PERMISSIONS = {read: true, write: true, manage: true}
+
def full_name
"#{first_name} #{last_name}"
end
+ def groups_i_can(verb)
+ self.group_permissions.select { |uuid, mask| mask[verb] }.keys
+ end
+
+ def self.invalidate_permissions_cache
+ Rails.cache.delete_matched(/^groups_for_user_/)
+ end
+
protected
def permission_to_create
end
true
end
+
+ def group_permissions
+ Rails.cache.fetch "groups_for_user_#{current_user.uuid}" do
+ permissions_from = {}
+ todo = {self.uuid => true}
+ done = {}
+ while !todo.empty?
+ lookup_uuids = todo.keys
+ lookup_uuids.each do |uuid| done[uuid] = true end
+ todo = {}
+ Link.where('tail_uuid in (?) and link_class = ? and head_kind = ?',
+ lookup_uuids,
+ 'permission',
+ 'orvos#group').each do |link|
+ unless done.has_key? link.head_uuid
+ todo[link.head_uuid] = true
+ end
+ link_permissions = {}
+ case link.name
+ when 'can_read'
+ link_permissions = {read:true}
+ when 'can_write'
+ link_permissions = {read:true,write:true}
+ when 'can_manage'
+ link_permissions = ALL_PERMISSIONS
+ end
+ permissions_from[link.tail_uuid] ||= {}
+ permissions_from[link.tail_uuid][link.head_uuid] ||= {}
+ link_permissions.each do |k,v|
+ permissions_from[link.tail_uuid][link.head_uuid][k] ||= v
+ end
+ end
+ end
+ search_permissions(self.uuid, permissions_from)
+ end
+ end
+
+ def search_permissions(start, graph, merged={}, upstream_mask=nil, upstream_path={})
+ nextpaths = graph[start]
+ return merged if !nextpaths
+ return merged if upstream_path.has_key? start
+ upstream_path[start] = true
+ upstream_mask ||= ALL_PERMISSIONS
+ nextpaths.each do |head, mask|
+ merged[head] ||= {}
+ mask.each do |k,v|
+ merged[head][k] ||= v if upstream_mask[k]
+ end
+ search_permissions(head, graph, merged, upstream_mask.select { |k,v| v && merged[head][k] }, upstream_path)
+ end
+ upstream_path.delete start
+ merged
+ end
end