Skip to content

Instantly share code, notes, and snippets.

@gumayunov
Created January 29, 2012 12:28
Show Gist options
  • Save gumayunov/1698579 to your computer and use it in GitHub Desktop.
Save gumayunov/1698579 to your computer and use it in GitHub Desktop.
OmniAuth::ReturnPathMiddleware
module OmniAuth
class ReturnPathMiddleware
def initialize(app)
@app = app
end
def call(env)
if auth_request?(env) && asseptable_referer?(env)
save_referer(env)
end
@app.call(env)
end
private
def auth_regexp
%r{^(?:/auth/\w+|/user/sign_\w\w)/?$}
end
def asseptable_referer?(env)
env['HTTP_REFERER'] !~ auth_regexp
end
def auth_request?(env)
env['REQUEST_PATH'] =~ auth_regexp
end
def save_referer(env)
referer = env['HTTP_REFERER']
Rails.logger.debug("return path to be saved in session: #{referer}")
env['rack.session']['auth.return_path'] = referer
end
end
end
# coding: UTF-8
require 'spec_helper'
shared_examples_for "path saver" do
it "saves HTTP_REFERER into session['auth.return_path']" do
user_visits('/page', @req_path)
saved_path.should == '/page'
end
it "saves nil if no HTTP_REFERER in env" do
user_visits(@req_path)
saved_path.should be_nil
end
it "does not overwrite entire session" do
session['existent_key'] = 1
user_visits('/page', @req_path)
session['existent_key'].should == 1
end
end
describe OmniAuth::ReturnPathMiddleware do
before :each do
@app = Proc.new {}
@env = { 'rack.session' => {} }
end
subject do
OmniAuth::ReturnPathMiddleware.new(@app)
end
def session
@env['rack.session']
end
def saved_path
session['auth.return_path']
end
def user_visits(*pages)
@prev_page = nil
pages.each do |page|
@env['HTTP_REFERER'] = @prev_page
@env['REQUEST_PATH'] = page
subject.call(@env)
@prev_page = page
end
end
context "REQUEST_PATH is /user/sign_in" do
before :each do
@req_path = '/user/sign_in'
end
it_behaves_like "path saver"
end
context "REQUEST_PATH is omiauth entry path /auth/:provider" do
before :each do
@req_path = '/auth/twitter'
end
it_behaves_like "path saver"
context "where are a few /user/sign* pages" do
it "preserves previously saved path" do
user_visits(*%w{
/page
/user/sign_in/
/user/sign_up
/auth/twitter/
})
saved_path.should == '/page'
user_visits(*%w{
/page1
/user/sign_in
/user/sign_up
/page2
/auth/twitter
})
saved_path.should == '/page2'
end
end
end
context "users returns from provider to callback or failure" do
it "does not affect saved path" do
pages = %w{
/page
/user/sign_in
/user/sign_up
/auth/twitter
}
# Редирект с социальной сети происходит без HTTP_REFERER
# поэтому используем nil, чтобы симулировать это
user_visits(*pages, nil, '/auth/twitter/callback')
saved_path.should == '/page'
user_visits(*pages, nil, '/auth/twitter/failure')
saved_path.should == '/page'
end
end
context "REQUEST_PATH is not omniauth path" do
it "does not touch session" do
user_visits('/page', '/noneauth/twitter')
saved_path.should be_nil
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment