File: lib/login_system.rb

Overview
Module Structure
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: LoginSystem#1
has properties
module method: included / 1 #2
method: current_user #12
method: current_user= / 1 #16
method: authenticate #27
method: authorize #42
method: user_has_access_to_action? / 1 #57
method: login_from_session #61
method: login_from_cookie #65
method: login_from_http #73
method: set_session_cookie / 1 #81
  module: ClassMethods#85
has properties
method: no_login_required #86
method: login_required? #91
method: login_required #95
method: only_allow_access_to / 1 #101
method: controller_permissions #111
method: user_has_access_to_action? / 3 #115

Code

   1  module LoginSystem
   2    def self.included(base)
   3      base.extend ClassMethods
   4      base.class_eval do
   5        prepend_before_filter :authenticate, :authorize
   6        helper_method :current_user
   7      end
   8    end
   9 
  10    protected
  11 
  12      def current_user
  13        @current_user ||= (login_from_session || login_from_cookie || login_from_http)
  14      end
  15      
  16      def current_user=(value=nil)
  17        if value && value.is_a?(User)
  18          @current_user = value
  19          session['user_id'] = value.id 
  20        else
  21          @current_user = nil
  22          session['user_id'] = nil
  23        end
  24        @current_user
  25      end
  26      
  27      def authenticate
  28        action = params['action'].to_s.intern
  29        if current_user
  30          session['user_id'] = current_user.id
  31          true
  32        else
  33          session[:return_to] = request.request_uri
  34          respond_to do |format|
  35            format.html { redirect_to login_url }
  36            format.any(:xml,:json) { request_http_basic_authentication }
  37          end
  38          false
  39        end
  40      end
  41 
  42      def authorize
  43        action = action_name.to_s.intern
  44        if user_has_access_to_action?(action)
  45          true
  46        else
  47          permissions = self.class.controller_permissions[action]
  48          flash[:error] = permissions[:denied_message] || 'Access denied.'
  49          respond_to do |format|
  50            format.html { redirect_to(permissions[:denied_url] || { :action => :index }) }
  51            format.any(:xml, :json) { head :forbidden }
  52          end
  53          false
  54        end
  55      end
  56 
  57      def user_has_access_to_action?(action)
  58        self.class.user_has_access_to_action?(current_user, action, self)
  59      end
  60 
  61      def login_from_session
  62        User.find(session['user_id']) rescue nil
  63      end
  64 
  65      def login_from_cookie
  66        if !cookies[:session_token].blank? && user = User.find_by_session_token(cookies[:session_token]) # don't find by empty value
  67          user.remember_me
  68          set_session_cookie(user)
  69          user
  70        end
  71      end
  72 
  73      def login_from_http
  74        if [Mime::XML, Mime::JSON].include?(request.format)
  75          authenticate_with_http_basic do |user_name, password|
  76            User.authenticate(user_name, password)
  77          end
  78        end
  79      end
  80 
  81      def set_session_cookie(user = current_user)
  82        cookies[:session_token] = { :value => user.session_token , :expires => Radiant::Config['session_timeout'].to_i.from_now.utc }
  83      end
  84 
  85    module ClassMethods
  86      def no_login_required
  87        skip_before_filter :authenticate
  88        skip_before_filter :authorize
  89      end
  90 
  91      def login_required?
  92        filter_chain.any? {|f| f.method == :authenticate || f.method == :authorize }
  93      end
  94 
  95      def login_required
  96        unless login_required?
  97          prepend_before_filter :authenticate, :authorize
  98        end
  99      end
 100 
 101      def only_allow_access_to(*args)
 102        options = {}
 103        options = args.pop.dup if args.last.kind_of?(Hash)
 104        options.symbolize_keys!
 105        actions = args.map { |a| a.to_s.intern }
 106        actions.each do |action|
 107          controller_permissions[action] = options
 108        end
 109      end
 110 
 111      def controller_permissions
 112        @controller_permissions ||= Hash.new { |h,k| h[k.to_s.intern] = Hash.new }
 113      end
 114      
 115      def user_has_access_to_action?(user, action, instance=new)
 116        permissions = controller_permissions[action.to_s.intern]
 117        case
 118        when allowed_roles = permissions[:when]
 119          allowed_roles = [allowed_roles].flatten
 120          allowed_roles.any? { |role| user.has_role?(role) }
 121        when condition_method = permissions[:if]
 122          instance.send(condition_method)
 123        else
 124          true
 125        end
 126      end
 127    end
 128  end