module Permissable::InstanceMethods
Public Class Methods
included(base)
click to toggle source
# File lib/permissable.rb, line 135 def self.included(base) base.define_singleton_method(:included) do |klass| klass.cattr_accessor :permissions_lookup klass.cattr_accessor :allow_cached_permissions klass.cattr_accessor :default_permission_scopes klass.default_permission_scopes = ['full'] klass.permissions_lookup = [] end end
Public Instance Methods
allows?(user, action, relevant_scopes=nil)
click to toggle source
# File lib/permissable.rb, line 71 def allows?(user, action, relevant_scopes=nil) relevant_scopes ||= user.permission_scopes if user && user.respond_to?(:permission_scopes) relevant_scopes ||= self.class.default_permission_scopes relevant_scopes += ['*'] unless relevant_scopes == ['none'] if self.class.allow_cached_permissions # check for an existing result keyed off the record's id and updated_at permissions = permissions_for(user, relevant_scopes) action.instance_variable_set('@scope_rejected', permissions[action] == false) return permissions[action] == true end scope_rejected = false self.class.permissions_lookup.each do |actions, block, allowed_scopes| next unless actions.include?(action.to_s) next if block.arity == 1 && !user res = instance_exec(user, &block) if res == true if (allowed_scopes & relevant_scopes).length > 0 return true else scope_rejected = true end end end action.instance_variable_set('@scope_rejected', !!scope_rejected) return false end
cache_key(prefix=nil)
click to toggle source
# File lib/permissable.rb, line 43 def cache_key(prefix=nil) id = self.id || 'nil' updated = (self.updated_at || Time.now).to_f key = "#{self.class.to_s}#{id}-#{updated}:#{Permissable.cache_token}" if prefix key = prefix + "/" + key end key end
clear_cached(prefix)
click to toggle source
# File lib/permissable.rb, line 67 def clear_cached(prefix) Permissable.permissions_redis.del(self.cache_key(prefix)) end
get_cached(prefix)
click to toggle source
# File lib/permissable.rb, line 58 def get_cached(prefix) cache_string = Permissable.permissions_redis.get(self.cache_key(prefix)) cache = nil if cache_string cache = JSON.parse(cache_string) rescue nil end cache end
permissions_for(user, relevant_scopes=nil)
click to toggle source
# File lib/permissable.rb, line 100 def permissions_for(user, relevant_scopes=nil) relevant_scopes ||= user.permission_scopes if user && user.respond_to?(:permission_scopes) relevant_scopes ||= self.class.default_permission_scopes relevant_scopes += ['*'] unless relevant_scopes == ['none'] if self.class.allow_cached_permissions cache_key = (user && user.cache_key) || "nobody" cache_key += "/scopes_#{relevant_scopes.join(',')}" permissions = get_cached("permissions-for/#{cache_key}") return permissions if permissions end granted_permissions = { 'user_id' => (user && user.global_id) } granted_permissions.with_indifferent_access if granted_permissions.respond_to?(:with_indifferent_access) self.class.permissions_lookup.each do |actions, block, allowed_scopes| already_granted = granted_permissions.select{|k, v| v == true }.map(&:first) next if block.arity == 1 && !user next if actions - already_granted == [] if instance_exec(user, &block) actions.each do |action| if (allowed_scopes & relevant_scopes).length > 0 granted_permissions[action] = true else granted_permissions[action] ||= false end end end end # cache the result with a 30-minute expiration keyed off the id and updated_at set_cached("permissions-for/#{cache_key}", granted_permissions) if self.class.allow_cached_permissions granted_permissions end
set_cached(prefix, data, expires=nil)
click to toggle source
# File lib/permissable.rb, line 53 def set_cached(prefix, data, expires=nil) expires ||= 1800 # 30 minutes Permissable.permissions_redis.setex(self.cache_key(prefix), expires, data.to_json) end