diff --git a/lib/omniauth/strategies/linkedin.rb b/lib/omniauth/strategies/linkedin.rb index aa7d409..c7f4795 100755 --- a/lib/omniauth/strategies/linkedin.rb +++ b/lib/omniauth/strategies/linkedin.rb @@ -6,12 +6,15 @@ class LinkedIn < OmniAuth::Strategies::OAuth2 # Give your strategy a name. option :name, 'linkedin' + option :authorize_options, [:scope, :state, :redirect_uri] + # This is where you pass the options you would pass when # initializing your consumer from the OAuth gem. option :client_options, { :site => 'https://api.linkedin.com', :authorize_url => 'https://www.linkedin.com/uas/oauth2/authorization?response_type=code', - :token_url => 'https://www.linkedin.com/uas/oauth2/accessToken' + :token_url => 'https://www.linkedin.com/uas/oauth2/accessToken', + :token_method => :get } option :token_params, { @@ -21,6 +24,16 @@ class LinkedIn < OmniAuth::Strategies::OAuth2 option :scope, 'r_basicprofile r_emailaddress' option :fields, ['id', 'email-address', 'first-name', 'last-name', 'headline', 'location', 'industry', 'picture-url', 'public-profile-url'] + def authorize_params + super.tap do |params| + options[:authorize_options].each do |k| + params[k] = request.params[k.to_s] unless [nil, ''].include?(request.params[k.to_s]) + end + + session['omniauth.state'] = params[:state] if params['state'] + end + end + # These are called after authentication has succeeded. If # possible, you should try to set the UID without making # additional calls (if the user id is returned with the token diff --git a/spec/omniauth/strategies/linkedin_oauth2_spec.rb b/spec/omniauth/strategies/linkedin_oauth2_spec.rb index 2c5c782..5abe077 100755 --- a/spec/omniauth/strategies/linkedin_oauth2_spec.rb +++ b/spec/omniauth/strategies/linkedin_oauth2_spec.rb @@ -2,7 +2,28 @@ require 'omniauth-linkedin-oauth2' describe OmniAuth::Strategies::LinkedIn do - subject { OmniAuth::Strategies::LinkedIn.new(nil) } + let(:request) { double('Request', :params => {}, :cookies => {}, :env => {}) } + let(:app) { + lambda do + [200, {}, ["Hello."]] + end + } + + subject do + OmniAuth::Strategies::LinkedIn.new(app, 'appid', 'secret', @options || {}).tap do |strategy| + strategy.stub(:request) { + request + } + end + end + + before do + OmniAuth.config.test_mode = true + end + + after do + OmniAuth.config.test_mode = false + end it 'should add a camelization for itself' do OmniAuth::Utils.camelize('linkedin').should == 'LinkedIn' @@ -79,15 +100,76 @@ end end - describe '#authorize_params' do - describe 'scope' do - before :each do - subject.stub(:session => {}) + describe "#authorize_options" do + [:scope, :state].each do |k| + it "should support #{k}" do + @options = {k => 'http://someval'} + subject.authorize_params[k.to_s].should eq('http://someval') + end + end + + describe 'redirect_uri' do + it 'should default to nil' do + @options = {} + subject.authorize_params['redirect_uri'].should eq(nil) + end + + it 'should set the redirect_uri parameter if present' do + @options = {:redirect_uri => 'https://example.com'} + subject.authorize_params['redirect_uri'].should eq('https://example.com') end + end - it 'sets default scope' do + describe 'scope' do + it 'should set default scope to r_basicprofile r_emailaddress' do subject.authorize_params['scope'].should eq('r_basicprofile r_emailaddress') end end + + describe 'state' do + it 'should set the state parameter' do + @options = {:state => 'some_state'} + subject.authorize_params['state'].should eq('some_state') + subject.session['omniauth.state'].should eq('some_state') + end + + it 'should set the omniauth.state dynamically' do + subject.stub(:request) { double('Request', {:params => {'state' => 'some_state'}, :env => {}}) } + subject.authorize_params['state'].should eq('some_state') + subject.session['omniauth.state'].should eq('some_state') + end + end + + describe "overrides" do + it 'should include top-level options that are marked as :authorize_options' do + @options = {:authorize_options => [:scope, :foo, :request_visible_actions], :scope => 'http://bar', :foo => 'baz', :hd => "wow", :request_visible_actions => "something"} + subject.authorize_params['scope'].should eq('http://bar') + subject.authorize_params['foo'].should eq('baz') + subject.authorize_params['hd'].should eq(nil) + subject.authorize_params['request_visible_actions'].should eq('something') + end + + describe "request overrides" do + [:scope, :state].each do |k| + context "authorize option #{k}" do + let(:request) { double('Request', :params => {k.to_s => 'http://example.com'}, :cookies => {}, :env => {}) } + + it "should set the #{k} authorize option dynamically in the request" do + @options = {k => ''} + subject.authorize_params[k.to_s].should eq('http://example.com') + end + end + end + + describe "custom authorize_options" do + let(:request) { double('Request', :params => {'foo' => 'something'}, :cookies => {}, :env => {}) } + + it "should support request overrides from custom authorize_options" do + @options = {:authorize_options => [:foo], :foo => ''} + subject.authorize_params['foo'].should eq('something') + end + end + end + end end end