| | 1 | module ActionController #:nodoc: |
|---|
| | 2 | module SessionManagement #:nodoc: |
|---|
| | 3 | def self.append_features(base) |
|---|
| | 4 | super |
|---|
| | 5 | base.extend(ClassMethods) |
|---|
| | 6 | base.class_eval do |
|---|
| | 7 | alias_method :process_without_session_management_support, :process |
|---|
| | 8 | alias_method :process, :process_with_session_management_support |
|---|
| | 9 | end |
|---|
| | 10 | end |
|---|
| | 11 | |
|---|
| | 12 | module ClassMethods |
|---|
| | 13 | # Specify how sessions ought to be managed for a subset of the actions on |
|---|
| | 14 | # the controller. Like filters, you can specify <tt>:only</tt> and |
|---|
| | 15 | # <tt>:except</tt> clauses to restrict the subset, otherwise options |
|---|
| | 16 | # apply to all actions on this controller. |
|---|
| | 17 | # |
|---|
| | 18 | # The session options are inheritable, as well, so if you specify them in |
|---|
| | 19 | # a parent controller, they apply to controllers that extend the parent. |
|---|
| | 20 | # |
|---|
| | 21 | # Usage: |
|---|
| | 22 | # |
|---|
| | 23 | # # turn off session management for all actions. |
|---|
| | 24 | # session :off |
|---|
| | 25 | # |
|---|
| | 26 | # # turn off session management for all actions _except_ foo and bar. |
|---|
| | 27 | # session :off, :except => %w(foo bar) |
|---|
| | 28 | # |
|---|
| | 29 | # # turn off session management for only the foo and bar actions. |
|---|
| | 30 | # session :off, :only => %w(foo bar) |
|---|
| | 31 | # |
|---|
| | 32 | # # the session will only work over HTTPS, but only for the foo action |
|---|
| | 33 | # session :only => :foo, :session_secure => true |
|---|
| | 34 | # |
|---|
| | 35 | # All session options described for ActionController::Base.process_cgi |
|---|
| | 36 | # are valid arguments. |
|---|
| | 37 | def session(*args) |
|---|
| | 38 | options = Hash === args.last ? args.pop : {} |
|---|
| | 39 | |
|---|
| | 40 | options[:disabled] = true if !args.empty? |
|---|
| | 41 | options[:only] = [*options[:only]].map { |o| o.to_s } if options[:only] |
|---|
| | 42 | options[:except] = [*options[:except]].map { |o| o.to_s } if options[:except] |
|---|
| | 43 | if options[:only] && options[:except] |
|---|
| | 44 | raise ArgumentError, "only one of either :only or :except are allowed" |
|---|
| | 45 | end |
|---|
| | 46 | |
|---|
| | 47 | write_inheritable_array("session_options", [options]) |
|---|
| | 48 | end |
|---|
| | 49 | |
|---|
| | 50 | def session_options_for(action) #:nodoc: |
|---|
| | 51 | options = {} |
|---|
| | 52 | |
|---|
| | 53 | action = action.to_s |
|---|
| | 54 | (read_inheritable_attribute("session_options") || []).each do |opts| |
|---|
| | 55 | if opts[:only] && opts[:only].include?(action) |
|---|
| | 56 | options.merge!(opts) |
|---|
| | 57 | elsif opts[:except] && !opts[:except].include?(action) |
|---|
| | 58 | options.merge!(opts) |
|---|
| | 59 | elsif !opts[:only] && !opts[:except] |
|---|
| | 60 | options.merge!(opts) |
|---|
| | 61 | end |
|---|
| | 62 | end |
|---|
| | 63 | |
|---|
| | 64 | options.delete :only |
|---|
| | 65 | options.delete :except |
|---|
| | 66 | |
|---|
| | 67 | options[:disabled] ? false : options |
|---|
| | 68 | end |
|---|
| | 69 | end |
|---|
| | 70 | |
|---|
| | 71 | def process_with_session_management_support(request, response, method = :perform_action, *arguments) #:nodoc: |
|---|
| | 72 | action = request.parameters["action"] || "index" |
|---|
| | 73 | request.session_options = self.class.session_options_for(action) |
|---|
| | 74 | process_without_session_management_support(request, response, method, *arguments) |
|---|
| | 75 | end |
|---|
| | 76 | end |
|---|
| | 77 | end |