forked from soveran/cuba
-
Notifications
You must be signed in to change notification settings - Fork 141
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add conditional_sessions plugin, for using the sessions plugin for on…
…ly a subset of requests
- Loading branch information
1 parent
e760a7d
commit e6c84e8
Showing
4 changed files
with
143 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# frozen-string-literal: true | ||
|
||
class Roda | ||
module RodaPlugins | ||
# The conditional_sessions plugin loads the sessions plugin. However, | ||
# it only allows sessions if the block passed to the plugin returns | ||
# truthy. The block is evaluated in request context. This is designed for | ||
# use in applications that want to use sessions for some requests, | ||
# and want to be sure that sessions are not used for other requests. | ||
# For example, if you want to make sure that sessions are not used for | ||
# requests with paths starting with /static, you could do: | ||
# | ||
# plugin :conditional_sessions, secret: ENV["SECRET"] do | ||
# !path_info.start_with?('/static') | ||
# end | ||
# | ||
# The the request session, session_created_at, and session_updated_at methods | ||
# raise a RodaError exception when sessions are not allowed. The request | ||
# persist_session and route scope clear_session methods do nothing when | ||
# sessions are not allowed. | ||
module ConditionalSessions | ||
# Pass all options to the sessions block, and use the block to define | ||
# a request method for whether sessions are allowed. | ||
def self.load_dependencies(app, opts=OPTS, &block) | ||
app.plugin :sessions, opts | ||
app::RodaRequest.class_eval do | ||
define_method(:use_sessions?, &block) | ||
alias use_sessions? use_sessions? | ||
end | ||
end | ||
|
||
module InstanceMethods | ||
# Do nothing if not using sessions. | ||
def clear_session | ||
super if @_request.use_sessions? | ||
end | ||
end | ||
|
||
module RequestMethods | ||
# Raise RodaError if not using sessions. | ||
def session | ||
raise RodaError, "session called on request not using sessions" unless use_sessions? | ||
super | ||
end | ||
|
||
# Raise RodaError if not using sessions. | ||
def session_created_at | ||
raise RodaError, "session_created_at called on request not using sessions" unless use_sessions? | ||
super | ||
end | ||
|
||
# Raise RodaError if not using sessions. | ||
def session_updated_at | ||
raise RodaError, "session_updated_at called on request not using sessions" unless use_sessions? | ||
super | ||
end | ||
|
||
# Do nothing if not using sessions. | ||
def persist_session(headers, session) | ||
super if use_sessions? | ||
end | ||
end | ||
end | ||
|
||
register_plugin(:conditional_sessions, ConditionalSessions) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
require_relative "../spec_helper" | ||
|
||
if RUBY_VERSION >= '2' | ||
describe "conditional_sessions plugin" do | ||
include CookieJar | ||
|
||
before do | ||
allow = @allow = String.new('f') | ||
app(:bare) do | ||
plugin :conditional_sessions, :secret=>'1'*64 do | ||
allow != 'f' | ||
end | ||
|
||
route do |r| | ||
r.get('s', String, String){|k, v| v.force_encoding('UTF-8'); session[k] = v} | ||
r.get('g', String){|k| session[k].to_s} | ||
r.get('cat'){r.session_created_at.to_i.to_s} | ||
r.get('uat'){r.session_updated_at.to_i.to_s} | ||
r.get('cs'){clear_session.to_s} | ||
r.get('ps', String, String){|k, v| r.persist_session(response.headers, k => v); env.delete("rack.session"); nil} | ||
'' | ||
end | ||
end | ||
end | ||
|
||
it "allows sessions if allowed" do | ||
@allow.replace('t') | ||
body('/s/foo/bar').must_equal 'bar' | ||
body('/g/foo').must_equal 'bar' | ||
body('/cat').to_i.must_be(:>=, Time.now.to_i - 1) | ||
body('/uat').to_i.must_be(:>=, Time.now.to_i - 1) | ||
|
||
body('/s/foo/baz').must_equal 'baz' | ||
body('/g/foo').must_equal 'baz' | ||
|
||
body('/ps/foo/quux').must_equal '' | ||
body('/g/foo').must_equal 'quux' | ||
|
||
body('/cs').must_equal '' | ||
body('/g/foo').must_equal '' | ||
end | ||
|
||
it "raises on session if sessions not allowed" do | ||
proc{body('/s/foo/bar')}.must_raise Roda::RodaError | ||
end | ||
|
||
it "raises on session_created_at if sessions not allowed" do | ||
proc{body('/cat')}.must_raise Roda::RodaError | ||
end | ||
|
||
it "raises on session_updated_at if sessions not allowed" do | ||
proc{body('/uat')}.must_raise Roda::RodaError | ||
end | ||
|
||
it "has clear_session do nothing if sessions are not alowed" do | ||
@allow.replace('t') | ||
body('/s/foo/bar').must_equal 'bar' | ||
@allow.replace('f') | ||
body('/cs').must_equal '' | ||
@allow.replace('t') | ||
body('/g/foo').must_equal 'bar' | ||
end | ||
|
||
it "has persist_session do nothing if sessions are not alowed" do | ||
@allow.replace('t') | ||
body('/s/foo/bar').must_equal 'bar' | ||
@allow.replace('f') | ||
body('/ps/foo/quux').must_equal '' | ||
@allow.replace('t') | ||
body('/g/foo').must_equal 'bar' | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters