omniauth-twitter-1.4.0/0000755000004100000410000000000013134072374015074 5ustar www-datawww-dataomniauth-twitter-1.4.0/Rakefile0000644000004100000410000000023213134072374016536 0ustar www-datawww-datarequire "bundler/gem_tasks" require 'rspec/core/rake_task' desc "Run specs" RSpec::Core::RakeTask.new desc 'Default: run specs.' task :default => :spec omniauth-twitter-1.4.0/omniauth-twitter.gemspec0000644000004100000410000000156713134072374021776 0ustar www-datawww-data# -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) require "omniauth-twitter/version" Gem::Specification.new do |s| s.name = "omniauth-twitter" s.version = OmniAuth::Twitter::VERSION s.authors = ["Arun Agrawal"] s.email = ["arunagw@gmail.com"] s.homepage = "https://github.com/arunagw/omniauth-twitter" s.description = %q{OmniAuth strategy for Twitter} s.summary = s.description s.license = "MIT" s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.require_paths = ["lib"] s.required_ruby_version = Gem::Requirement.new('>= 1.9.3') s.add_dependency 'omniauth-oauth', '~> 1.1' s.add_dependency 'rack' s.add_development_dependency 'bundler', '~> 1.0' end omniauth-twitter-1.4.0/Gemfile0000644000004100000410000000057313134072374016374 0ustar www-datawww-datasource 'https://rubygems.org' gemspec gem 'rake' group :test do if Gem::Version.create(RUBY_VERSION) < Gem::Version.create("2.0.0") # for jruby 1.7.x gem "addressable", "2.4.0" end if Gem::Version.create(RUBY_VERSION) < Gem::Version.create("2.2.2") gem "rack", "~> 1.6" end gem 'rspec', '~> 3.2' gem 'rack-test' gem 'simplecov' gem 'webmock' end omniauth-twitter-1.4.0/.rspec0000644000004100000410000000001113134072374016201 0ustar www-datawww-data--colour omniauth-twitter-1.4.0/spec/0000755000004100000410000000000013134072374016026 5ustar www-datawww-dataomniauth-twitter-1.4.0/spec/omniauth/0000755000004100000410000000000013134072374017652 5ustar www-datawww-dataomniauth-twitter-1.4.0/spec/omniauth/strategies/0000755000004100000410000000000013134072374022024 5ustar www-datawww-dataomniauth-twitter-1.4.0/spec/omniauth/strategies/twitter_spec.rb0000644000004100000410000001564013134072374025073 0ustar www-datawww-datarequire 'spec_helper' describe OmniAuth::Strategies::Twitter do let(:request) { double('Request', :params => {}, :cookies => {}, :env => {}) } subject do args = ['appid', 'secret', @options || {}].compact OmniAuth::Strategies::Twitter.new(*args).tap do |strategy| allow(strategy).to receive(:request) { request } end end describe 'client options' do it 'should have correct name' do expect(subject.options.name).to eq('twitter') end it 'should have correct site' do expect(subject.options.client_options.site).to eq('https://api.twitter.com') end it 'should have correct authorize url' do expect(subject.options.client_options.authorize_path).to eq('/oauth/authenticate') end end describe 'info' do before do allow(subject).to receive(:raw_info).and_return(raw_info_hash) end it 'should returns the nickname' do expect(subject.info[:nickname]).to eq(raw_info_hash['screen_name']) end it 'should returns the name' do expect(subject.info[:name]).to eq(raw_info_hash['name']) end it 'should returns the email' do expect(subject.info[:email]).to eq(raw_info_hash['email']) end it 'should returns the location' do expect(subject.info[:location]).to eq(raw_info_hash['location']) end it 'should returns the description' do expect(subject.info[:description]).to eq(raw_info_hash['description']) end it 'should returns the urls' do expect(subject.info[:urls]['Website']).to eq(raw_info_hash['url']) expect(subject.info[:urls]['Twitter']).to eq("https://twitter.com/#{raw_info_hash['screen_name']}") end end describe 'image_size option' do context 'when user has an image' do it 'should return image with size specified' do @options = { :image_size => 'original' } allow(subject).to receive(:raw_info).and_return( { 'profile_image_url' => 'http://twimg0-a.akamaihd.net/sticky/default_profile_images/default_profile_0_normal.png' } ) expect(subject.info[:image]).to eq('http://twimg0-a.akamaihd.net/sticky/default_profile_images/default_profile_0.png') end it 'should return bigger image when bigger size specified' do @options = { :image_size => 'bigger' } allow(subject).to receive(:raw_info).and_return( { 'profile_image_url' => 'http://twimg0-a.akamaihd.net/sticky/default_profile_images/default_profile_0_normal.png' } ) expect(subject.info[:image]).to eq('http://twimg0-a.akamaihd.net/sticky/default_profile_images/default_profile_0_bigger.png') end it 'should return secure image with size specified' do @options = { :secure_image_url => 'true', :image_size => 'mini' } allow(subject).to receive(:raw_info).and_return( { 'profile_image_url_https' => 'https://twimg0-a.akamaihd.net/sticky/default_profile_images/default_profile_0_normal.png' } ) expect(subject.info[:image]).to eq('https://twimg0-a.akamaihd.net/sticky/default_profile_images/default_profile_0_mini.png') end it 'should return normal image by default' do allow(subject).to receive(:raw_info).and_return( { 'profile_image_url' => 'http://twimg0-a.akamaihd.net/sticky/default_profile_images/default_profile_0_normal.png' } ) expect(subject.info[:image]).to eq('http://twimg0-a.akamaihd.net/sticky/default_profile_images/default_profile_0_normal.png') end end end describe 'skip_info option' do context 'when skip info option is enabled' do it 'should not include raw_info in extras hash' do @options = { :skip_info => true } allow(subject).to receive(:raw_info).and_return({:foo => 'bar'}) expect(subject.extra[:raw_info]).to eq(nil) end end end describe 'request_phase' do context 'with no request params set and x_auth_access_type specified' do before do allow(subject).to receive(:request).and_return( double('Request', {:params => {'x_auth_access_type' => 'read'}}) ) allow(subject).to receive(:old_request_phase).and_return(:whatever) end it 'should not break' do expect { subject.request_phase }.not_to raise_error end end context "with no request params set and use_authorize options provided" do before do @options = { :use_authorize => true } allow(subject).to receive(:request) do double('Request', {:params => {} }) end allow(subject).to receive(:old_request_phase) { :whatever } end it "should switch authorize_path from authenticate to authorize" do expect { subject.request_phase }.to change { subject.options.client_options.authorize_path }.from('/oauth/authenticate').to('/oauth/authorize') end end context 'with a specified callback_url in the params' do before do params = { 'callback_url' => 'http://foo.dev/auth/twitter/foobar' } allow(subject).to receive(:request) do double('Request', :params => params) end allow(subject).to receive(:session) do double('Session', :[] => { 'callback_url' => params['callback_url'] }) end allow(subject).to receive(:old_request_phase) { :whatever } end it 'should use the callback_url' do expect(subject.callback_url).to eq 'http://foo.dev/auth/twitter/foobar' end it 'should return the correct callback_path' do expect(subject.callback_path).to eq '/auth/twitter/foobar' end end context 'with no callback_url set' do before do allow(subject).to receive(:request) do double('Request', :params => {}) end allow(subject).to receive(:session) do double('Session', :[] => {}) end allow(subject).to receive(:old_request_phase) { :whatever } allow(subject).to receive(:old_callback_url).and_return(:old_callback) end it 'callback_url should return nil' do expect(subject.callback_url).to eq :old_callback end it 'should return the default callback_path value' do expect(subject.callback_path).to eq '/auth/twitter/callback' end end context "with no request params set and force_login specified" do before do allow(subject).to receive(:request) do double('Request', {:params => { 'force_login' => true } }) end allow(subject).to receive(:old_request_phase) { :whatever } end it "should change add force_login=true to authorize_params" do expect { subject.request_phase }.to change {subject.options.authorize_params.force_login}.from(nil).to(true) end end end end private def raw_info_hash { 'screen_name' => 'foo', 'name' => 'Foo Bar', 'email' => 'foo@example.com', 'location' => 'India', 'description' => 'Developer', 'url' => 'example.com/foobar' } end omniauth-twitter-1.4.0/spec/spec_helper.rb0000644000004100000410000000076613134072374020655 0ustar www-datawww-data$:.unshift File.expand_path('..', __FILE__) $:.unshift File.expand_path('../../lib', __FILE__) require 'simplecov' SimpleCov.start do minimum_coverage(94.59) end require 'rspec' require 'rack/test' require 'webmock/rspec' require 'omniauth' require 'omniauth-twitter' RSpec.configure do |config| config.include WebMock::API config.include Rack::Test::Methods config.extend OmniAuth::Test::StrategyMacros, :type => :strategy config.expect_with :rspec do |c| c.syntax = :expect end end omniauth-twitter-1.4.0/.travis.yml0000644000004100000410000000020313134072374017200 0ustar www-datawww-datadist: trusty rvm: - 2.1.10 - 2.2.6 - 2.3.3 - 2.4.0 - jruby-1.7.26 - rbx-3 matrix: allow_failures: - rvm: rbx-3 omniauth-twitter-1.4.0/lib/0000755000004100000410000000000013134072374015642 5ustar www-datawww-dataomniauth-twitter-1.4.0/lib/omniauth/0000755000004100000410000000000013134072374017466 5ustar www-datawww-dataomniauth-twitter-1.4.0/lib/omniauth/strategies/0000755000004100000410000000000013134072374021640 5ustar www-datawww-dataomniauth-twitter-1.4.0/lib/omniauth/strategies/twitter.rb0000644000004100000410000000537513134072374023701 0ustar www-datawww-datarequire 'omniauth-oauth' require 'json' module OmniAuth module Strategies class Twitter < OmniAuth::Strategies::OAuth option :name, 'twitter' option :client_options, {:authorize_path => '/oauth/authenticate', :site => 'https://api.twitter.com', :proxy => ENV['http_proxy'] ? URI(ENV['http_proxy']) : nil} uid { access_token.params[:user_id] } info do { :nickname => raw_info['screen_name'], :name => raw_info['name'], :email => raw_info["email"], :location => raw_info['location'], :image => image_url, :description => raw_info['description'], :urls => { 'Website' => raw_info['url'], 'Twitter' => "https://twitter.com/#{raw_info['screen_name']}", } } end extra do skip_info? ? {} : { :raw_info => raw_info } end def raw_info @raw_info ||= JSON.load(access_token.get('/1.1/account/verify_credentials.json?include_entities=false&skip_status=true&include_email=true').body) rescue ::Errno::ETIMEDOUT raise ::Timeout::Error end alias :old_request_phase :request_phase def request_phase %w[force_login lang screen_name].each do |v| if request.params[v] options[:authorize_params][v.to_sym] = request.params[v] end end %w[x_auth_access_type].each do |v| if request.params[v] options[:request_params][v.to_sym] = request.params[v] end end if options[:use_authorize] || request.params['use_authorize'] == 'true' options[:client_options][:authorize_path] = '/oauth/authorize' else options[:client_options][:authorize_path] = '/oauth/authenticate' end old_request_phase end alias :old_callback_url :callback_url def callback_url if request.params['callback_url'] request.params['callback_url'] else old_callback_url end end def callback_path params = session['omniauth.params'] if params.nil? || params['callback_url'].nil? super else URI(params['callback_url']).path end end private def image_url original_url = options[:secure_image_url] ? raw_info['profile_image_url_https'] : raw_info['profile_image_url'] case options[:image_size] when 'mini' original_url.sub('normal', 'mini') when 'bigger' original_url.sub('normal', 'bigger') when 'original' original_url.sub('_normal', '') else original_url end end end end end omniauth-twitter-1.4.0/lib/omniauth-twitter/0000755000004100000410000000000013134072374021166 5ustar www-datawww-dataomniauth-twitter-1.4.0/lib/omniauth-twitter/version.rb0000644000004100000410000000010113134072374023170 0ustar www-datawww-datamodule OmniAuth module Twitter VERSION = "1.4.0" end end omniauth-twitter-1.4.0/lib/omniauth-twitter.rb0000644000004100000410000000011113134072374021504 0ustar www-datawww-datarequire "omniauth-twitter/version" require 'omniauth/strategies/twitter' omniauth-twitter-1.4.0/.gitignore0000644000004100000410000000005213134072374017061 0ustar www-datawww-data*.gem .bundle Gemfile.lock pkg/* coverage omniauth-twitter-1.4.0/CONTRIBUTING.md0000644000004100000410000000240313134072374017324 0ustar www-datawww-data# Contributing For the best chance of having your changes merged, please: * Fork the project. * Make your feature addition or bug fix. * Add tests for it. This is important so it is not accidentally broken in a future version. * Commit, do not mess with rakefile, version, or history. (If you want to have your own version, that is fine but bump version in a commit by itself so it can be ignored when pulled). * Send a pull request. Bonus points for topic branches. If your proposed changes only affect documentation, include the following on a new line in each of your commit messages: ``` [ci skip] ``` This will signal [Travis](https://travis-ci.org) that running the test suite is not necessary for these changes. # Reporting Bugs If you are experiencing unexpected behavior and, after having read [omniauth](https://github.com/intridea/omniauth) and [omniauth-twitter](https://github.com/arunagw/omniauth-twitter)'s documentation, are convinced this behavior is a bug, please: 1. [Search](https://github.com/arunagw/omniauth-twitter/issues) existing issues. 2. Collect enough information to reproduce the issue: * omniauth-twitter version * Ruby version * Specific setup conditions * Description of expected behavior * Description of actual behavior omniauth-twitter-1.4.0/README.md0000644000004100000410000002240613134072374016357 0ustar www-datawww-data# OmniAuth Twitter [![Gem Version](https://badge.fury.io/rb/omniauth-twitter.svg)](http://badge.fury.io/rb/omniauth-twitter) [![CI Build Status](https://secure.travis-ci.org/arunagw/omniauth-twitter.svg?branch=master)](http://travis-ci.org/arunagw/omniauth-twitter) [![Code Climate](https://codeclimate.com/github/arunagw/omniauth-twitter.png)](https://codeclimate.com/github/arunagw/omniauth-twitter) This gem contains the Twitter strategy for OmniAuth. Twitter offers a few different methods of integration. This strategy implements the browser variant of the "[Sign in with Twitter](https://dev.twitter.com/docs/auth/implementing-sign-twitter)" flow. Twitter uses OAuth 1.0a. Twitter's developer area contains ample documentation on how it implements this, so check that out if you are really interested in the details. ## Before You Begin You should have already installed OmniAuth into your app; if not, read the [OmniAuth README](https://github.com/intridea/omniauth) to get started. Now sign in into the [Twitter developer area](https://dev.twitter.com/apps) and create an application. Take note of your API Key and API Secret (not the Access Token and Access Token Secret) because that is what your web application will use to authenticate against the Twitter API. Make sure to set a callback URL or else you may get authentication errors. (It doesn't matter what it is, just that it is set.) ## Using This Strategy First start by adding this gem to your Gemfile: ```ruby gem 'omniauth-twitter' ``` If you need to use the latest HEAD version, you can do so with: ```ruby gem 'omniauth-twitter', :github => 'arunagw/omniauth-twitter' ``` Next, tell OmniAuth about this provider. For a Rails app, your `config/initializers/omniauth.rb` file should look like this: ```ruby Rails.application.config.middleware.use OmniAuth::Builder do provider :twitter, "API_KEY", "API_SECRET" end ``` Replace `"API_KEY"` and `"API_SECRET"` with the appropriate values you obtained [earlier](https://apps.twitter.com). ## Authentication Options Twitter supports a [few options](https://dev.twitter.com/docs/api/1/get/oauth/authenticate) when authenticating. Usually you would specify these options as query parameters to the Twitter API authentication url (`https://api.twitter.com/oauth/authenticate` by default). With OmniAuth, of course, you use `http://yourapp.com/auth/twitter` instead. Because of this, this OmniAuth provider will pick up the query parameters you pass to the `/auth/twitter` URL and re-use them when making the call to the Twitter API. The options are: * **force_login** - This option sends the user to a sign-in screen to enter their Twitter credentials, even if they are already signed in. This is handy when your application supports multiple Twitter accounts and you want to ensure the correct user is signed in. *Example:* `http://yoursite.com/auth/twitter?force_login=true` * **screen_name** - This option implies **force_login**, except the screen name field is pre-filled with a particular value. *Example:* `http://yoursite.com/auth/twitter?screen_name=jim` * **lang** - The language used in the Twitter prompt. This is useful for adding i18n support since the language of the prompt can be dynamically set for each user. *Example:* `http://yoursite.com/auth/twitter?lang=pt` * **secure_image_url** - Set to `true` to use https for the user's image url. Default is `false`. * **image_size**: This option defines the size of the user's image. Valid options include `mini` (24x24), `normal` (48x48), `bigger` (73x73) and `original` (the size of the image originally uploaded). Default is `normal`. * **x_auth_access_type** - This option (described [here](https://dev.twitter.com/docs/api/1/post/oauth/request_token)) lets you request the level of access that your app will have to the Twitter account in question. *Example:* `http://yoursite.com/auth/twitter?x_auth_access_type=read` * **use_authorize** - There are actually two URLs you can use against the Twitter API. As mentioned, the default is `https://api.twitter.com/oauth/authenticate`, but you also have `https://api.twitter.com/oauth/authorize`. Passing this option as `true` will use the second URL rather than the first. What's the difference? As described [here](https://dev.twitter.com/docs/api/1/get/oauth/authenticate), with `authenticate`, if your user has already granted permission to your application, Twitter will redirect straight back to your application, whereas `authorize` forces the user to go through the "grant permission" screen again. For certain use cases this may be necessary. *Example:* `http://yoursite.com/auth/twitter?use_authorize=true`. *Note:* You must have "Allow this application to be used to Sign in with Twitter" checked in [your application's settings](https://dev.twitter.com/apps) - without it your user will be asked to authorize your application each time they log in. Here's an example of a possible configuration where the the user's original profile picture is returned over https, the user is always prompted to sign-in and the default language of the Twitter prompt is changed: ```ruby Rails.application.config.middleware.use OmniAuth::Builder do provider :twitter, "API_KEY", "API_SECRET", { :secure_image_url => 'true', :image_size => 'original', :authorize_params => { :force_login => 'true', :lang => 'pt' } } end ``` ## Authentication Hash An example auth hash available in `request.env['omniauth.auth']`: ```ruby { :provider => "twitter", :uid => "123456", :info => { :nickname => "johnqpublic", :name => "John Q Public", :location => "Anytown, USA", :image => "http://si0.twimg.com/sticky/default_profile_images/default_profile_2_normal.png", :description => "a very normal guy.", :urls => { :Website => nil, :Twitter => "https://twitter.com/johnqpublic" } }, :credentials => { :token => "a1b2c3d4...", # The OAuth 2.0 access token :secret => "abcdef1234" }, :extra => { :access_token => "", # An OAuth::AccessToken object :raw_info => { :name => "John Q Public", :listed_count => 0, :profile_sidebar_border_color => "181A1E", :url => nil, :lang => "en", :statuses_count => 129, :profile_image_url => "http://si0.twimg.com/sticky/default_profile_images/default_profile_2_normal.png", :profile_background_image_url_https => "https://twimg0-a.akamaihd.net/profile_background_images/229171796/pattern_036.gif", :location => "Anytown, USA", :time_zone => "Chicago", :follow_request_sent => false, :id => 123456, :profile_background_tile => true, :profile_sidebar_fill_color => "666666", :followers_count => 1, :default_profile_image => false, :screen_name => "", :following => false, :utc_offset => -3600, :verified => false, :favourites_count => 0, :profile_background_color => "1A1B1F", :is_translator => false, :friends_count => 1, :notifications => false, :geo_enabled => true, :profile_background_image_url => "http://twimg0-a.akamaihd.net/profile_background_images/229171796/pattern_036.gif", :protected => false, :description => "a very normal guy.", :profile_link_color => "2FC2EF", :created_at => "Thu Jul 4 00:00:00 +0000 2013", :id_str => "123456", :profile_image_url_https => "https://si0.twimg.com/sticky/default_profile_images/default_profile_2_normal.png", :default_profile => false, :profile_use_background_image => false, :entities => { :description => { :urls => [] } }, :profile_text_color => "666666", :contributors_enabled => false } } } ``` ## Watch the RailsCast Ryan Bates has put together an excellent RailsCast on OmniAuth: [![RailsCast #241](http://railscasts.com/static/episodes/stills/241-simple-omniauth-revised.png "RailsCast #241 - Simple OmniAuth (revised)")](http://railscasts.com/episodes/241-simple-omniauth-revised) ## Supported Rubies OmniAuth Twitter is tested under 2.1.x, 2.2.x and JRuby. If you use its gem on ruby 1.9.x, 2.0.x, or Rubinius use version v1.2.1 . ## Contributing Please read the [contribution guidelines](CONTRIBUTING.md) for some information on how to get started. No contribution is too small. ## License Copyright (c) 2011 by Arun Agrawal Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.