twitter-login 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/twitter/login.rb +34 -57
- data/spec/login_spec.rb +19 -16
- metadata +7 -7
    
        data/lib/twitter/login.rb
    CHANGED
    
    | @@ -10,36 +10,38 @@ class Twitter::Login | |
| 10 10 | 
             
              attr_reader :options
         | 
| 11 11 |  | 
| 12 12 | 
             
              class << self
         | 
| 13 | 
            -
                attr_accessor :consumer_key, :secret
         | 
| 13 | 
            +
                attr_accessor :consumer_key, :secret, :site
         | 
| 14 14 | 
             
              end
         | 
| 15 15 |  | 
| 16 | 
            -
              DEFAULTS = { | 
| 16 | 
            +
              DEFAULTS = {
         | 
| 17 | 
            +
                :return_to => '/',
         | 
| 18 | 
            +
                :site => 'http://api.twitter.com',
         | 
| 19 | 
            +
                :authorize_path => '/oauth/authenticate'
         | 
| 20 | 
            +
              }
         | 
| 17 21 |  | 
| 18 | 
            -
              def initialize( | 
| 19 | 
            -
                @app = app
         | 
| 22 | 
            +
              def initialize(options)
         | 
| 20 23 | 
             
                @options = DEFAULTS.merge options
         | 
| 21 24 | 
             
                self.class.consumer_key, self.class.secret = @options[:consumer_key], @options[:secret]
         | 
| 25 | 
            +
                self.class.site = @options[:site]
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
              
         | 
| 28 | 
            +
              def login_handler(options = {})
         | 
| 29 | 
            +
                @options.update options
         | 
| 30 | 
            +
                return self
         | 
| 22 31 | 
             
              end
         | 
| 23 32 |  | 
| 24 33 | 
             
              def call(env)
         | 
| 25 34 | 
             
                request = Request.new(env)
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                if request | 
| 28 | 
            -
                   | 
| 29 | 
            -
                   | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
                    end
         | 
| 34 | 
            -
                  elsif request[:denied]
         | 
| 35 | 
            -
                    # user refused to log in with Twitter, so give up
         | 
| 36 | 
            -
                    handle_denied_access(request)
         | 
| 37 | 
            -
                  else
         | 
| 38 | 
            -
                    # user clicked to login; send them to Twitter
         | 
| 39 | 
            -
                    redirect_to_twitter(request)
         | 
| 40 | 
            -
                  end
         | 
| 35 | 
            +
              
         | 
| 36 | 
            +
                if request[:oauth_verifier]
         | 
| 37 | 
            +
                  # user authorized the app
         | 
| 38 | 
            +
                  handle_twitter_authorization(request)
         | 
| 39 | 
            +
                elsif request[:denied]
         | 
| 40 | 
            +
                  # user refused to log in with Twitter
         | 
| 41 | 
            +
                  handle_denied_access(request)
         | 
| 41 42 | 
             
                else
         | 
| 42 | 
            -
                   | 
| 43 | 
            +
                  # starting the login process; send user to Twitter
         | 
| 44 | 
            +
                  redirect_to_twitter(request)
         | 
| 43 45 | 
             
                end
         | 
| 44 46 | 
             
              end
         | 
| 45 47 |  | 
| @@ -50,7 +52,7 @@ class Twitter::Login | |
| 50 52 |  | 
| 51 53 | 
             
                def twitter_oauth
         | 
| 52 54 | 
             
                  OAuth::Consumer.new Twitter::Login.consumer_key, Twitter::Login.secret,
         | 
| 53 | 
            -
                    :site =>  | 
| 55 | 
            +
                    :site => Twitter::Login.site
         | 
| 54 56 | 
             
                end
         | 
| 55 57 |  | 
| 56 58 | 
             
                def twitter_user
         | 
| @@ -92,36 +94,23 @@ class Twitter::Login | |
| 92 94 | 
             
                # create a request token and store its parameter in session
         | 
| 93 95 | 
             
                request_token = oauth.get_request_token(:oauth_callback => request.url)
         | 
| 94 96 | 
             
                request.session[:twitter_request_token] = [request_token.token, request_token.secret]
         | 
| 97 | 
            +
                
         | 
| 95 98 | 
             
                # redirect to Twitter authorization page
         | 
| 96 99 | 
             
                redirect request_token.authorize_url
         | 
| 97 100 | 
             
              end
         | 
| 98 101 |  | 
| 99 102 | 
             
              def handle_twitter_authorization(request)
         | 
| 100 103 | 
             
                access_token = authorize_from_request(request)
         | 
| 101 | 
            -
                response = access_token.get('/1/account/verify_credentials.json')
         | 
| 102 104 |  | 
| 103 105 | 
             
                # get and store authenticated user's info from Twitter
         | 
| 104 | 
            -
                 | 
| 105 | 
            -
                
         | 
| 106 | 
            -
                # pass the request down to the main app
         | 
| 107 | 
            -
                response = begin
         | 
| 108 | 
            -
                  yield
         | 
| 109 | 
            -
                rescue
         | 
| 110 | 
            -
                  raise unless $!.class.name == 'ActionController::RoutingError'
         | 
| 111 | 
            -
                  [404]
         | 
| 112 | 
            -
                end
         | 
| 106 | 
            +
                response = access_token.get('/1/account/verify_credentials.json')
         | 
| 107 | 
            +
                request.session[:twitter_user] = Yajl::Parser.parse response.body
         | 
| 113 108 |  | 
| 114 | 
            -
                 | 
| 115 | 
            -
                if response[0].to_i == 404
         | 
| 116 | 
            -
                  # if not, redirect to :return_to path
         | 
| 117 | 
            -
                  redirect_to_return_path(request)
         | 
| 118 | 
            -
                else
         | 
| 119 | 
            -
                  # use the response from the app without modification
         | 
| 120 | 
            -
                  response
         | 
| 121 | 
            -
                end
         | 
| 109 | 
            +
                redirect_to_return_path(request)
         | 
| 122 110 | 
             
              end
         | 
| 123 111 |  | 
| 124 112 | 
             
              def handle_denied_access(request)
         | 
| 113 | 
            +
                # cleanup session and set an error identifier
         | 
| 125 114 | 
             
                request.session[:twitter_request_token] = nil # work around a Rails 2.3.5 bug
         | 
| 126 115 | 
             
                request.session.delete(:twitter_request_token)
         | 
| 127 116 | 
             
                request.session[:twitter_error] = 'user_denied'
         | 
| @@ -134,11 +123,11 @@ class Twitter::Login | |
| 134 123 | 
             
              def authorize_from_request(request)
         | 
| 135 124 | 
             
                rtoken, rsecret = request.session[:twitter_request_token]
         | 
| 136 125 | 
             
                request_token = OAuth::RequestToken.new(oauth, rtoken, rsecret)
         | 
| 137 | 
            -
                access_token = request_token.get_access_token(:oauth_verifier => request[:oauth_verifier])
         | 
| 138 126 |  | 
| 139 | 
            -
                 | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 127 | 
            +
                request_token.get_access_token(:oauth_verifier => request[:oauth_verifier]).tap do |access_token|
         | 
| 128 | 
            +
                  request.session.delete(:twitter_request_token)
         | 
| 129 | 
            +
                  request.session[:twitter_access_token] = [access_token.token, access_token.secret]
         | 
| 130 | 
            +
                end
         | 
| 142 131 | 
             
              end
         | 
| 143 132 |  | 
| 144 133 | 
             
              def redirect_to_return_path(request)
         | 
| @@ -150,19 +139,7 @@ class Twitter::Login | |
| 150 139 | 
             
              end
         | 
| 151 140 |  | 
| 152 141 | 
             
              def oauth
         | 
| 153 | 
            -
                 | 
| 154 | 
            -
                  :site =>  | 
| 155 | 
            -
                  :authorize_path => '/oauth/authenticate'
         | 
| 156 | 
            -
                )
         | 
| 157 | 
            -
              end
         | 
| 158 | 
            -
              
         | 
| 159 | 
            -
              def user_hash_from_response(api_response)
         | 
| 160 | 
            -
                parse_response(api_response).reject { |key, _|
         | 
| 161 | 
            -
                  key == 'status' or key =~ /^profile_|_color$/
         | 
| 162 | 
            -
                }
         | 
| 163 | 
            -
              end
         | 
| 164 | 
            -
              
         | 
| 165 | 
            -
              def parse_response(api_response)
         | 
| 166 | 
            -
                Yajl::Parser.parse api_response.body
         | 
| 142 | 
            +
                OAuth::Consumer.new options[:consumer_key], options[:secret],
         | 
| 143 | 
            +
                  :site => options[:site], :authorize_path => options[:authorize_path]
         | 
| 167 144 | 
             
              end
         | 
| 168 145 | 
             
            end
         | 
    
        data/spec/login_spec.rb
    CHANGED
    
    | @@ -44,35 +44,38 @@ describe Twitter::Login do | |
| 44 44 |  | 
| 45 45 | 
             
              it "should login with Twitter" do
         | 
| 46 46 | 
             
                request_token = mock('Request Token', :authorize_url => 'http://disney.com/oauth', :token => 'abc', :secret => '123')
         | 
| 47 | 
            -
                oauth = mock_oauth('Twitter OAuth')
         | 
| 48 | 
            -
                oauth.should_receive(: | 
| 47 | 
            +
                oauth = mock_oauth('Twitter OAuth', :request_token => request_token)
         | 
| 48 | 
            +
                oauth.should_receive(:set_callback_url).with('http://example.org/login')
         | 
| 49 49 |  | 
| 50 50 | 
             
                get('/login', :lint => true)
         | 
| 51 51 | 
             
                response.status.should == 302
         | 
| 52 52 | 
             
                response['Location'].should == 'http://disney.com/oauth'
         | 
| 53 53 | 
             
                response.body.should be_empty
         | 
| 54 | 
            -
                session[: | 
| 54 | 
            +
                session[:request_token].should == ['abc', '123']
         | 
| 55 55 | 
             
              end
         | 
| 56 56 |  | 
| 57 57 | 
             
              it "should authorize with Twitter" do
         | 
| 58 | 
            -
                 | 
| 59 | 
            -
                request_token = mock('Request Token')
         | 
| 60 | 
            -
                OAuth::RequestToken.should_receive(:new).with(oauth, 'abc', '123').and_return(request_token)
         | 
| 58 | 
            +
                consumer = mock('OAuth consumer')
         | 
| 61 59 | 
             
                access_token = mock('Access Token', :token => 'access1', :secret => '42')
         | 
| 62 | 
            -
                 | 
| 60 | 
            +
                oauth = mock_oauth('Twitter OAuth', :access_token => access_token, :consumer => consumer)
         | 
| 61 | 
            +
                oauth.should_receive(:authorize_from_request).with('abc', '123', 'allrighty')
         | 
| 63 62 |  | 
| 64 | 
            -
                 | 
| 65 | 
            -
             | 
| 63 | 
            +
                twitter = mock('Twitter Base')
         | 
| 64 | 
            +
                Twitter::Base.should_receive(:new).with(oauth).and_return(twitter)
         | 
| 66 65 |  | 
| 67 | 
            -
                 | 
| 68 | 
            -
             | 
| 66 | 
            +
                twitter.should_receive(:verify_credentials).and_return {
         | 
| 67 | 
            +
                  Hashie::Mash.new :screen_name => 'faker',
         | 
| 68 | 
            +
                    :name => 'Fake Jr.', :profile_image_url => 'http://disney.com/mickey.png',
         | 
| 69 | 
            +
                    :followers_count => '13', :friends_count => '6', :statuses_count => '52'
         | 
| 70 | 
            +
                }
         | 
| 69 71 |  | 
| 70 | 
            -
                session_data = {: | 
| 72 | 
            +
                session_data = {:request_token => ['abc', '123']}
         | 
| 71 73 | 
             
                get('/login?oauth_verifier=allrighty', build_session(session_data).update(:lint => true))
         | 
| 72 74 | 
             
                response.status.should == 302
         | 
| 73 75 | 
             
                response['Location'].should == 'http://example.org/'
         | 
| 74 | 
            -
                session[: | 
| 75 | 
            -
                session[: | 
| 76 | 
            +
                session[:request_token].should be_nil
         | 
| 77 | 
            +
                session[:access_token].should == ['access1', '42']
         | 
| 78 | 
            +
                session[:oauth_consumer].should be_nil
         | 
| 76 79 |  | 
| 77 80 | 
             
                current_user = session[:twitter_user]
         | 
| 78 81 | 
             
                current_user['screen_name'].should == 'faker'
         | 
| @@ -83,7 +86,7 @@ describe Twitter::Login do | |
| 83 86 | 
             
                get('/login?denied=OMG', build_session(session_data).update(:lint => true))
         | 
| 84 87 | 
             
                response.status.should == 302
         | 
| 85 88 | 
             
                response['Location'].should == 'http://example.org/'
         | 
| 86 | 
            -
                session[: | 
| 89 | 
            +
                session[:request_token].should be_nil
         | 
| 87 90 | 
             
              end
         | 
| 88 91 |  | 
| 89 92 | 
             
              protected
         | 
| @@ -121,7 +124,7 @@ describe Twitter::Login do | |
| 121 124 |  | 
| 122 125 | 
             
              def mock_oauth(*args)
         | 
| 123 126 | 
             
                consumer = mock(*args)
         | 
| 124 | 
            -
                OAuth | 
| 127 | 
            +
                Twitter::OAuth.should_receive(:new).and_return(consumer)
         | 
| 125 128 | 
             
                consumer
         | 
| 126 129 | 
             
              end
         | 
| 127 130 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: twitter-login
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              hash:  | 
| 5 | 
            -
              prerelease: 
         | 
| 4 | 
            +
              hash: 15
         | 
| 5 | 
            +
              prerelease: false
         | 
| 6 6 | 
             
              segments: 
         | 
| 7 7 | 
             
              - 0
         | 
| 8 | 
            -
              -  | 
| 9 | 
            -
              -  | 
| 10 | 
            -
              version: 0. | 
| 8 | 
            +
              - 4
         | 
| 9 | 
            +
              - 0
         | 
| 10 | 
            +
              version: 0.4.0
         | 
| 11 11 | 
             
            platform: ruby
         | 
| 12 12 | 
             
            authors: 
         | 
| 13 13 | 
             
            - "Mislav Marohni\xC4\x87"
         | 
| @@ -15,7 +15,7 @@ autorequire: | |
| 15 15 | 
             
            bindir: bin
         | 
| 16 16 | 
             
            cert_chain: []
         | 
| 17 17 |  | 
| 18 | 
            -
            date:  | 
| 18 | 
            +
            date: 2010-09-17 00:00:00 -07:00
         | 
| 19 19 | 
             
            default_executable: 
         | 
| 20 20 | 
             
            dependencies: 
         | 
| 21 21 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -140,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 140 140 | 
             
            requirements: []
         | 
| 141 141 |  | 
| 142 142 | 
             
            rubyforge_project: 
         | 
| 143 | 
            -
            rubygems_version: 1. | 
| 143 | 
            +
            rubygems_version: 1.3.7
         | 
| 144 144 | 
             
            signing_key: 
         | 
| 145 145 | 
             
            specification_version: 3
         | 
| 146 146 | 
             
            summary: Rack middleware to provide login functionality through Twitter
         |