Skip to content

Instantly share code, notes, and snippets.

@mdeniz
Forked from hennevogel/forbidden_project_ids.rb
Created February 17, 2016 16:47
Show Gist options
  • Save mdeniz/ebd8f2bcf79c5fc99d32 to your computer and use it in GitHub Desktop.
Save mdeniz/ebd8f2bcf79c5fc99d32 to your computer and use it in GitHub Desktop.
# this is to speed up secure Project.find
def self.forbidden_project_ids
# Admins don't have forbidden projects
return [0] if User.current && User.current.is_admin?
# This will cache and return an array:
# {projecs: [p1,p2], whitelist: { u1: [p1], u2: [p1,p2], u3: [p2] } }
forbidden_projects = Rails.cache.fetch('forbidden_projects') do
forbidden_projects_hash = {projects: [], whitelist: {}}
Relationship.find_by_sql("SELECT ur.project_id, ur.user_id from flags f,
relationships ur where f.flag = 'access' and f.status = 'disable' and ur.project_id = f.project_id").each do |r|
forbidden_projects_hash[:projects] << r.project_id
forbidden_projects_hash[:whitelist][r.user_id] ||= []
forbidden_projects_hash[:whitelist][r.user_id] << r.project_id if r.user_id
end
forbidden_projects_hash[:projects].uniq!
forbidden_projects_hash[:projects] << 0 if forbidden_projects_hash[:projects].empty?
forbidden_projects_hash
end
# We don't need to check the relationships if we don't have a User
return forbidden_project[:projects] if User.current.nil? || User.current.is_nobody?
# 'cache_sequence_for_forbidden_projects' is for invalidating forbidden projects by users cache entries
cache_sequence = Rails.cache.fetch('cache_sequence_for_forbidden_projects') || 0
Rails.cache.fetch("users/#{User.current.id}-forbidden_projects-#{cache_sequence}") do
# Normal users can be in the whitelist then we substract allowed projects
whitelistened_projects_for_user = forbidden_project[:whitelist][User.current.id] || []
result = forbidden_project[:projects] - whitelistened_projects_for_user
end
end
def self.discard_cache
# 'cache_sequence_for_forbidden_projects' is for invalidating forbidden projects by users cache entries
# just increasing the sequence whe you want to discard those entries
new_cache_sequence = Rails.cache.fetch('cache_sequence_for_forbidden_projects') { 0 } + 1
Rails.cache.write('cache_sequence_for_forbidden_projects', new_cache_sequence)
Rails.cache.delete(FORBIDDEN_PROJECT_IDS_CACHE_KEY)
User.current.discard_cache if User.current
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment