Module: Roda::RodaPlugins::RouteCsrf::InstanceMethods
- Defined in:
- lib/roda/plugins/route_csrf.rb
Instance Method Summary collapse
-
#check_csrf!(opts = OPTS, &block) ⇒ Object
Check that the submitted CSRF token is valid, if the request requires a CSRF token.
-
#csrf_field ⇒ Object
The name of the hidden input tag containing the CSRF token.
-
#csrf_formaction_tag(path, *args) ⇒ Object
An HTML hidden input tag string containing the CSRF token, used for inputs with formaction, so the same form can be used to submit to multiple endpoints depending on which button was clicked.
-
#csrf_header ⇒ Object
The HTTP header name to use when submitting CSRF tokens in an HTTP header, if such support is enabled (it is not by default).
-
#csrf_metatag ⇒ Object
An HTML meta tag string containing a CSRF token that is not request-specific.
-
#csrf_path(action) ⇒ Object
Given a form action, return the appropriate path to use for the CSRF token.
-
#csrf_tag(*args) ⇒ Object
An HTML hidden input tag string containing the CSRF token.
-
#csrf_token(path = nil, method = ('POST' if path)) ⇒ Object
The value of the csrf token.
-
#use_request_specific_csrf_tokens? ⇒ Boolean
Whether request-specific CSRF tokens should be used by default.
-
#valid_csrf?(opts = OPTS) ⇒ Boolean
Whether the submitted CSRF token is valid for the request.
Instance Method Details
#check_csrf!(opts = OPTS, &block) ⇒ Object
Check that the submitted CSRF token is valid, if the request requires a CSRF token. If the CSRF token is valid or the request does not require a CSRF token, return nil. Otherwise, if a block is given, treat it as a routing block and yield to it, and if a block is not given, use the :csrf_failure option to determine how to handle it.
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/roda/plugins/route_csrf.rb', line 220 def check_csrf!(opts=OPTS, &block) if msg = (opts) if block @_request.on(&block) end case failure_action = opts.fetch(:csrf_failure, [:csrf_failure]) when :raise raise InvalidToken, msg when :empty_403 @_response.status = 403 headers = @_response.headers headers.clear headers[RodaResponseHeaders::CONTENT_TYPE] = 'text/html' headers[RodaResponseHeaders::CONTENT_LENGTH] ='0' throw :halt, @_response.finish_with_body([]) when :clear_session RodaPlugins.warn "Passing :clear_session as the :csrf_failure option to check_csrf! is deprecated" session.clear when :csrf_failure_method @_request.on{_roda_route_csrf_failure(@_request)} when Proc RodaPlugins.warn "Passing a Proc as the :csrf_failure option value to check_csrf! is deprecated" @_request.on{instance_exec(@_request, &failure_action)} # Deprecated else raise RodaError, "Unsupported :csrf_failure option: #{failure_action.inspect}" end end end |
#csrf_field ⇒ Object
The name of the hidden input tag containing the CSRF token. Also used as the name for the meta tag.
252 253 254 |
# File 'lib/roda/plugins/route_csrf.rb', line 252 def csrf_field [:field] end |
#csrf_formaction_tag(path, *args) ⇒ Object
An HTML hidden input tag string containing the CSRF token, used for inputs with formaction, so the same form can be used to submit to multiple endpoints depending on which button was clicked. See csrf_token for arguments, but the path argument is required.
290 291 292 |
# File 'lib/roda/plugins/route_csrf.rb', line 290 def csrf_formaction_tag(path, *args) "<input type=\"hidden\" name=\"#{csrf_options[:formaction_field]}[#{Rack::Utils.escape_html(path)}]\" value=\"#{csrf_token(path, *args)}\" \/>" end |
#csrf_header ⇒ Object
The HTTP header name to use when submitting CSRF tokens in an HTTP header, if such support is enabled (it is not by default).
258 259 260 |
# File 'lib/roda/plugins/route_csrf.rb', line 258 def csrf_header [:header] end |
#csrf_metatag ⇒ Object
An HTML meta tag string containing a CSRF token that is not request-specific. It is not recommended to use this, as it doesn't support request-specific tokens.
264 265 266 |
# File 'lib/roda/plugins/route_csrf.rb', line 264 def "<meta name=\"#{csrf_field}\" content=\"#{csrf_token}\" \/>" end |
#csrf_path(action) ⇒ Object
Given a form action, return the appropriate path to use for the CSRF token. This makes it easier to generate request-specific tokens without having to worry about the different types of form actions (relative paths, absolute paths, URLs, empty paths).
272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/roda/plugins/route_csrf.rb', line 272 def csrf_path(action) case action when nil, '', /\A[#?]/ # use current path request.path when /\A(?:https?:\/)?\// # Either full URI or absolute path, extract just the path URI.parse(action).path else # relative path, join to current path URI.join(request.url, action).path end end |
#csrf_tag(*args) ⇒ Object
An HTML hidden input tag string containing the CSRF token. See csrf_token for arguments.
296 297 298 |
# File 'lib/roda/plugins/route_csrf.rb', line 296 def csrf_tag(*args) "<input type=\"hidden\" name=\"#{csrf_field}\" value=\"#{csrf_token(*args)}\" \/>" end |
#csrf_token(path = nil, method = ('POST' if path)) ⇒ Object
The value of the csrf token. For a path specific token, provide a path argument. By default, it a path is provided, the POST request method will be assumed. To generate a token for a non-POST request method, pass the method as the second argument.
304 305 306 307 308 |
# File 'lib/roda/plugins/route_csrf.rb', line 304 def csrf_token(path=nil, method=('POST' if path)) token = SecureRandom.random_bytes(31) token << csrf_hmac(token, method, path) [token].pack("m0") end |
#use_request_specific_csrf_tokens? ⇒ Boolean
Whether request-specific CSRF tokens should be used by default.
311 312 313 |
# File 'lib/roda/plugins/route_csrf.rb', line 311 def use_request_specific_csrf_tokens? [:require_request_specific_tokens] end |
#valid_csrf?(opts = OPTS) ⇒ Boolean
Whether the submitted CSRF token is valid for the request. True if the request does not require a CSRF token.
317 318 319 |
# File 'lib/roda/plugins/route_csrf.rb', line 317 def valid_csrf?(opts=OPTS) (opts).nil? end |