Class: Twurl::OAuthClient

Inherits:
Object
  • Object
show all
Defined in:
lib/twurl/oauth_client.rb

Constant Summary collapse

OAUTH_CLIENT_OPTIONS =
%w[username consumer_key consumer_secret token secret]
METHODS =
{
  :post => Net::HTTP::Post,
  :get => Net::HTTP::Get,
  :put => Net::HTTP::Put,
  :delete => Net::HTTP::Delete,
  :options => Net::HTTP::Options,
  :head => Net::HTTP::Head,
  :copy => Net::HTTP::Copy
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ OAuthClient

Returns a new instance of OAuthClient.



55
56
57
58
59
60
61
62
63
# File 'lib/twurl/oauth_client.rb', line 55

def initialize(options = {})
  @username        = options['username']
  @password        = options['password']
  @consumer_key    = options['consumer_key']
  @consumer_secret = options['consumer_secret']
  @token           = options['token']
  @secret          = options['secret']
  configure_http!
end

Instance Attribute Details

#passwordObject (readonly)

Returns the value of attribute password.



54
55
56
# File 'lib/twurl/oauth_client.rb', line 54

def password
  @password
end

#usernameObject (readonly)

Returns the value of attribute username.



54
55
56
# File 'lib/twurl/oauth_client.rb', line 54

def username
  @username
end

Class Method Details

.load_client_for_username(username) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/twurl/oauth_client.rb', line 30

def load_client_for_username(username)
  if user_profiles = rcfile[username]
    if user_profiles.values.size == 1
      new(user_profiles.values.first)
    else
      raise Exception, "There is more than one consumer key associated with #{username}. Please specify which consumer key you want as well."
    end
  else
    raise Exception, "No profile for #{username}"
  end
end

.load_client_for_username_and_consumer_key(username, consumer_key) ⇒ Object



21
22
23
24
25
26
27
28
# File 'lib/twurl/oauth_client.rb', line 21

def load_client_for_username_and_consumer_key(username, consumer_key)
  user_profiles = rcfile[username]
  if user_profiles && attributes = user_profiles[consumer_key]
    new(attributes)
  else
    raise Exception, "No profile for #{username}"
  end
end

.load_default_clientObject

Raises:



46
47
48
49
# File 'lib/twurl/oauth_client.rb', line 46

def load_default_client
  raise Exception, "You must authorize first" unless rcfile.default_profile
  load_client_for_username_and_consumer_key(*rcfile.default_profile)
end

.load_from_options(options) ⇒ Object



11
12
13
14
15
16
17
18
19
# File 'lib/twurl/oauth_client.rb', line 11

def load_from_options(options)
  if rcfile.has_oauth_profile_for_username_with_consumer_key?(options.username, options.consumer_key)
    load_client_for_username_and_consumer_key(options.username, options.consumer_key)
  elsif options.username || (options.command == 'authorize')
    load_new_client_from_options(options)
  else
    load_default_client
  end
end

.load_new_client_from_options(options) ⇒ Object



42
43
44
# File 'lib/twurl/oauth_client.rb', line 42

def load_new_client_from_options(options)
  new(options.oauth_client_options.merge('password' => options.password))
end

.rcfile(reload = false) ⇒ Object



4
5
6
7
8
9
# File 'lib/twurl/oauth_client.rb', line 4

def rcfile(reload = false)
  if reload || @rcfile.nil?
    @rcfile = RCFile.new
  end
  @rcfile
end

Instance Method Details

#access_tokenObject



172
173
174
# File 'lib/twurl/oauth_client.rb', line 172

def access_token
  @access_token ||= OAuth::AccessToken.new(consumer, token, secret)
end

#authorized?Boolean

Returns:

  • (Boolean)


123
124
125
126
# File 'lib/twurl/oauth_client.rb', line 123

def authorized?
  oauth_response = fetch_verify_credentials
  oauth_response.class == Net::HTTPOK
end

#client_auth_parametersObject



93
94
95
# File 'lib/twurl/oauth_client.rb', line 93

def client_auth_parameters
  {'x_auth_username' => username, 'x_auth_password' => password, 'x_auth_mode' => 'client_auth'}
end

#configure_http!Object



154
155
156
157
158
159
160
# File 'lib/twurl/oauth_client.rb', line 154

def configure_http!
  consumer.http.set_debug_output(Twurl.options.debug_output_io) if Twurl.options.trace
  if Twurl.options.ssl?
    consumer.http.use_ssl     = true
    consumer.http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  end
end

#consumerObject



162
163
164
165
166
167
168
169
170
# File 'lib/twurl/oauth_client.rb', line 162

def consumer
  @consumer ||=
    OAuth::Consumer.new(
      consumer_key,
      consumer_secret,
      :site => Twurl.options.base_url,
      :proxy => Twurl.options.proxy
    )
end

#exchange_credentials_for_access_tokenObject



83
84
85
86
87
88
89
90
91
# File 'lib/twurl/oauth_client.rb', line 83

def exchange_credentials_for_access_token
  response = begin
    consumer.token_request(:post, consumer.access_token_path, nil, {}, client_auth_parameters)
  rescue OAuth::Unauthorized
    perform_pin_authorize_workflow
  end
  @token   = response[:oauth_token]
  @secret  = response[:oauth_token_secret]
end

#fetch_verify_credentialsObject



119
120
121
# File 'lib/twurl/oauth_client.rb', line 119

def fetch_verify_credentials
  access_token.get('/1.1/account/verify_credentials.json?include_entities=false&skip_status=true')
end

#generate_authorize_urlObject



105
106
107
108
109
110
111
112
113
# File 'lib/twurl/oauth_client.rb', line 105

def generate_authorize_url
  request = consumer.create_signed_request(:get, consumer.authorize_path, @request_token, pin_auth_parameters)
  params = request['Authorization'].sub(/^OAuth\s+/, '').split(/,\s+/).map { |p|
    k, v = p.split('=')
    v =~ /"(.*?)"/
    "#{k}=#{CGI::escape($1)}"
  }.join('&')
  "#{Twurl.options.base_url}#{request.path}?#{params}"
end

#needs_to_authorize?Boolean

Returns:

  • (Boolean)


128
129
130
# File 'lib/twurl/oauth_client.rb', line 128

def needs_to_authorize?
  token.nil? || secret.nil?
end

#perform_pin_authorize_workflowObject



97
98
99
100
101
102
103
# File 'lib/twurl/oauth_client.rb', line 97

def perform_pin_authorize_workflow
  @request_token = consumer.get_request_token
  CLI.puts("Go to #{generate_authorize_url} and paste in the supplied PIN")
  pin = gets
  access_token = @request_token.get_access_token(:oauth_verifier => pin.chomp)
  {:oauth_token => access_token.token, :oauth_token_secret => access_token.secret}
end

#perform_request_from_options(options, &block) ⇒ Object



75
76
77
78
79
80
81
# File 'lib/twurl/oauth_client.rb', line 75

def perform_request_from_options(options, &block)
  request_class = METHODS.fetch(options.request_method.to_sym)
  request = request_class.new(options.path, options.headers)
  request.set_form_data(options.data) if options.data
  request.oauth!(consumer.http, consumer, access_token)
  consumer.http.request(request, &block)
end

#pin_auth_parametersObject



115
116
117
# File 'lib/twurl/oauth_client.rb', line 115

def pin_auth_parameters
  {'oauth_callback' => 'oob'}
end

#saveObject



132
133
134
135
# File 'lib/twurl/oauth_client.rb', line 132

def save
  verify_has_username
  self.class.rcfile << self
end

#to_hashObject



145
146
147
148
149
150
151
152
# File 'lib/twurl/oauth_client.rb', line 145

def to_hash
  OAUTH_CLIENT_OPTIONS.inject({}) do |hash, attribute|
    if value = send(attribute)
      hash[attribute] = value
    end
    hash
  end
end

#verify_has_usernameObject



137
138
139
140
141
142
143
# File 'lib/twurl/oauth_client.rb', line 137

def verify_has_username
  if username.nil? || username == ''
    oauth_response = fetch_verify_credentials
    oauth_response.body =~ /"screen_name"\s*:\s*"(.*?)"/
    @username = $1
  end
end