1 module ActionController
#:nodoc:
2 module Verification
#:nodoc:
3 def self.included(base
) #:nodoc:
4 base
.extend(ClassMethods
)
7 # This module provides a class-level method for specifying that certain
8 # actions are guarded against being called without certain prerequisites
9 # being met. This is essentially a special kind of before_filter.
11 # An action may be guarded against being invoked without certain request
12 # parameters being set, or without certain session values existing.
14 # When a verification is violated, values may be inserted into the flash, and
15 # a specified redirection is triggered. If no specific action is configured,
16 # verification failures will by default result in a 400 Bad Request response.
20 # class GlobalController < ActionController::Base
21 # # Prevent the #update_settings action from being invoked unless
22 # # the 'admin_privileges' request parameter exists. The
23 # # settings action will be redirected to in current controller
24 # # if verification fails.
25 # verify :params => "admin_privileges", :only => :update_post,
26 # :redirect_to => { :action => "settings" }
28 # # Disallow a post from being updated if there was no information
29 # # submitted with the post, and if there is no active post in the
30 # # session, and if there is no "note" key in the flash. The route
31 # # named category_url will be redirected to if verification fails.
33 # verify :params => "post", :session => "post", "flash" => "note",
34 # :only => :update_post,
35 # :add_flash => { "alert" => "Failed to create your message" },
36 # :redirect_to => :category_url
38 # Note that these prerequisites are not business rules. They do not examine
39 # the content of the session or the parameters. That level of validation should
40 # be encapsulated by your domain model or helper methods in the controller.
42 # Verify the given actions so that if certain prerequisites are not met,
43 # the user is redirected to a different action. The +options+ parameter
44 # is a hash consisting of the following key/value pairs:
47 # a single key or an array of keys that must be in the <tt>params</tt>
48 # hash in order for the action(s) to be safely called.
50 # a single key or an array of keys that must be in the <tt>session</tt>
51 # in order for the action(s) to be safely called.
53 # a single key or an array of keys that must be in the flash in order
54 # for the action(s) to be safely called.
56 # a single key or an array of keys--any one of which must match the
57 # current request method in order for the action(s) to be safely called.
58 # (The key should be a symbol: <tt>:get</tt> or <tt>:post</tt>, for
61 # true/false option to ensure that the request is coming from an Ajax
63 # <tt>:add_flash</tt>::
64 # a hash of name/value pairs that should be merged into the session's
65 # flash if the prerequisites cannot be satisfied.
66 # <tt>:add_headers</tt>::
67 # a hash of name/value pairs that should be merged into the response's
68 # headers hash if the prerequisites cannot be satisfied.
69 # <tt>:redirect_to</tt>::
70 # the redirection parameters to be used when redirecting if the
71 # prerequisites cannot be satisfied. You can redirect either to named
72 # route or to the action in some controller.
74 # the render parameters to be used when the prerequisites cannot be satisfied.
76 # only apply this verification to the actions specified in the associated
77 # array (may also be a single value).
79 # do not apply this verification to the actions specified in the associated
80 # array (may also be a single value).
81 def verify(options
={})
82 before_filter
:only => options
[:only], :except => options
[:except] do |c
|
83 c
.__send__
:verify_action, options
90 def verify_action(options
) #:nodoc:
91 if prereqs_invalid
?(options
)
92 flash
.update(options
[:add_flash]) if options
[:add_flash]
93 response
.headers
.update(options
[:add_headers]) if options
[:add_headers]
94 apply_remaining_actions(options
) unless performed
?
98 def prereqs_invalid
?(options
) # :nodoc:
99 verify_presence_of_keys_in_hash_flash_or_params(options
) ||
100 verify_method(options
) ||
101 verify_request_xhr_status(options
)
104 def verify_presence_of_keys_in_hash_flash_or_params(options
) # :nodoc:
105 [*options
[:params] ].find
{ |v
| params
[v
].nil? } ||
106 [*options
[:session]].find
{ |v
| session
[v
].nil? } ||
107 [*options
[:flash] ].find
{ |v
| flash
[v
].nil? }
110 def verify_method(options
) # :nodoc:
111 [*options
[:method]].all
? { |v
| request
.method
!= v
.to_sym
} if options
[:method]
114 def verify_request_xhr_status(options
) # :nodoc:
115 request
.xhr
? != options
[:xhr] unless options
[:xhr].nil?
118 def apply_redirect_to(redirect_to_option
) # :nodoc:
119 (redirect_to_option
.is_a
?(Symbol
) && redirect_to_option
!= :back) ? self.__send__(redirect_to_option
) : redirect_to_option
122 def apply_remaining_actions(options
) # :nodoc:
124 when options
[:render] ; render(options
[:render])
125 when options
[:redirect_to] ; redirect_to(apply_redirect_to(options
[:redirect_to]))
126 else head(:bad_request)