Created
January 29, 2012 12:28
-
-
Save gumayunov/1698579 to your computer and use it in GitHub Desktop.
OmniAuth::ReturnPathMiddleware
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
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 |
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
# 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