Class: RubyDesk::Connector
- Inherits:
-
Object
- Object
- RubyDesk::Connector
- Defined in:
- lib/ruby_desk/connector.rb
Overview
Basic methods used for connecting with oDesk like signing request parameters and parsing response. This class is also responsible for authorizing user
Constant Summary collapse
- ODESK_URL =
"www.odesk.com/"
- ODESK_API_URL =
"#{ODESK_URL}api/"
- ODESK_GDS_URL =
"#{ODESK_URL}gds/"
- ODESK_AUTH_URL =
"#{ODESK_URL}services/api/auth/"
- DEFAULT_OPTIONS =
{:secure=>true, :sign=>true, :format=>'json', :base_url=>ODESK_API_URL, :auth=>true}
Instance Attribute Summary collapse
-
#auth_user ⇒ Object
Returns the value of attribute auth_user.
-
#frob ⇒ Object
writeonly
Sets the attribute frob.
Instance Method Summary collapse
-
#auth_url ⇒ Object
Returns the URL that authenticates the application for the current user.
-
#check_token ⇒ Object
Returns the authenticated user associated with the given authorization token.
-
#desktop_auth_url ⇒ Object
Returns a URL that the desktop user should visit to activate current frob.
-
#get_frob ⇒ Object
Returns an authentication frob.
-
#get_token ⇒ Object
Returns an authentication frob.
-
#initialize(api_key = nil, api_secret = nil, api_token = nil) ⇒ Connector
constructor
A new instance of Connector.
-
#invoke_api_call(api_call) ⇒ Object
invokes the given API call and returns body of the response as text.
-
#logout_url ⇒ Object
return the URL that logs user out of odesk applications.
-
#prepare_and_invoke_api_call(path, options = {}) ⇒ Object
Prepares an API call with the given arguments then invokes it and returns its body.
-
#prepare_api_call(path, options = {}) ⇒ Object
Returns the correct URL to go to to invoke the given api path: the path of the API to call.
-
#revoke_token ⇒ Object
Revokes the given aut Parameters * api_key * api_sig * api_token.
-
#sign(params) ⇒ Object
Sign the given parameters and returns the signature.
Constructor Details
#initialize(api_key = nil, api_secret = nil, api_token = nil) ⇒ Connector
Returns a new instance of Connector.
22 23 24 25 26 |
# File 'lib/ruby_desk/connector.rb', line 22 def initialize(api_key=nil, api_secret=nil, api_token=nil) @api_key = api_key @api_secret = api_secret @api_token = api_token end |
Instance Attribute Details
#auth_user ⇒ Object
Returns the value of attribute auth_user.
20 21 22 |
# File 'lib/ruby_desk/connector.rb', line 20 def auth_user @auth_user end |
#frob=(value) ⇒ Object (writeonly)
Sets the attribute frob
19 20 21 |
# File 'lib/ruby_desk/connector.rb', line 19 def frob=(value) @frob = value end |
Instance Method Details
#auth_url ⇒ Object
Returns the URL that authenticates the application for the current user. This is used for web applications only
134 135 136 137 138 139 |
# File 'lib/ruby_desk/connector.rb', line 134 def auth_url auth_call = prepare_api_call("", :params=>{:api_key=>@api_key}, :base_url=>ODESK_AUTH_URL, :format=>nil, :method=>:get, :auth=>false) data = auth_call[:params].to_a.map{|pair| pair.join '='}.join('&') return auth_call[:url]+"?"+data end |
#check_token ⇒ Object
Returns the authenticated user associated with the given authorization token.
Parameters
* api_key
* api_sig
* api_token
Return Data
* token
198 199 200 201 202 |
# File 'lib/ruby_desk/connector.rb', line 198 def check_token json = prepare_and_invoke_api_call 'auth/v1/keys/token', :method=>:get # TODO what to do with results? return json end |
#desktop_auth_url ⇒ Object
Returns a URL that the desktop user should visit to activate current frob. This method should not be called before a frob has been requested
143 144 145 146 147 148 149 |
# File 'lib/ruby_desk/connector.rb', line 143 def desktop_auth_url raise "Frob should be requested first. Use RubyDesk::Controller#get_frob()" unless @frob auth_call = prepare_api_call("", :params=>{:api_key=>@api_key, :frob=>@frob}, :base_url=>ODESK_AUTH_URL, :format=>nil, :method=>:get, :auth=>false) data = auth_call[:params].to_a.map{|pair| pair.join '='}.join('&') return auth_call[:url]+"?"+data end |
#get_frob ⇒ Object
Returns an authentication frob. Parameters
* api_key
* api_sig
Return Data
* frob
182 183 184 185 186 |
# File 'lib/ruby_desk/connector.rb', line 182 def get_frob json = prepare_and_invoke_api_call 'auth/v1/keys/frobs', :params=>{:api_key=>@api_key}, :method=>:post, :auth=>false @frob = json['frob'] end |
#get_token ⇒ Object
Returns an authentication frob.
Parameters
* frob
* api_key
* api_sig
Return Data
* token
166 167 168 169 170 171 172 |
# File 'lib/ruby_desk/connector.rb', line 166 def get_token json = prepare_and_invoke_api_call 'auth/v1/keys/tokens', :params=>{:frob=>@frob, :api_key=>@api_key}, :method=>:post, :auth=>false @auth_user = User.new(json['auth_user']) @api_token = json['token'] end |
#invoke_api_call(api_call) ⇒ Object
invokes the given API call and returns body of the response as text
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/ruby_desk/connector.rb', line 79 def invoke_api_call(api_call) url = URI.parse(api_call[:url]) http = Net::HTTP.new(url.host, url.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE # Concatenate parameters to form data data = api_call[:params].to_a.map{|pair| pair.map{|x| URI.escape(x.to_s)}.join '='}.join('&') headers = { 'Content-Type' => 'application/x-www-form-urlencoded' } RubyDesk.logger.info "URL: #{api_call[:url]}" RubyDesk.logger.info "method: #{api_call[:method]}" RubyDesk.logger.info "Params: #{data}" case api_call[:method] when :get, 'get' then resp, data = http.request(Net::HTTP::Get.new(url.path+"?"+data, headers)) when :post, 'post' then resp, data = http.request(Net::HTTP::Post.new(url.path, headers), data) when :delete, 'delete' then resp, data = http.request(Net::HTTP::Delete.new(url.path, headers), data) end RubyDesk.logger.info "Response code: #{resp.code}" RubyDesk.logger.info "Returned data: #{data}" case resp.code when "200" then return data when "400" then raise RubyDesk::BadRequest, data when "401", "403" then raise RubyDesk::UnauthorizedError, data when "404" then raise RubyDesk::PageNotFound, data when "500" then raise RubyDesk::ServerError, data else raise RubyDesk::Error, data end end |
#logout_url ⇒ Object
return the URL that logs user out of odesk applications
152 153 154 155 156 |
# File 'lib/ruby_desk/connector.rb', line 152 def logout_url logout_call = prepare_api_call("", :base_url=>ODESK_AUTH_URL, :secure=>false, :auth=>false, :format=>nil) return logout_call[:url] end |
#prepare_and_invoke_api_call(path, options = {}) ⇒ Object
Prepares an API call with the given arguments then invokes it and returns its body
119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/ruby_desk/connector.rb', line 119 def prepare_and_invoke_api_call(path, = {}) api_call = prepare_api_call(path, ) data = invoke_api_call(api_call) parsed_data = case [:format] when 'json' then JSON.parse(data) when 'xml' then REXML::Document.new(data) else JSON.parse(data) rescue REXML::Document.new(data) rescue data end RubyDesk.logger.info "Parsed data: #{parsed_data.inspect}" return parsed_data end |
#prepare_api_call(path, options = {}) ⇒ Object
Returns the correct URL to go to to invoke the given api path: the path of the API to call. e.g. ‘auth’ options:
-
:secure=>false: Whether a secure connection is required or not.
-
:sign=>true: Whether you need to sign the parameters or not. If :scure is false, parameters are not signed regardless of this option.
-
:params=>{}: a hash of parameters that needs to be appended
-
:auth=>true: when true indicates that this call need authentication.
This forces adding :api_token, :api_key and :api_sig to parameters. This means that parameters are automatically signed regardless of other options
64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/ruby_desk/connector.rb', line 64 def prepare_api_call(path, = {}) = DEFAULT_OPTIONS.merge() params = [:params] || {} if [:auth] params[:api_token] ||= @api_token params[:api_key] ||= @api_key end params[:api_sig] = sign(params) if ([:secure] && [:sign]) || [:auth] url = ([:secure] ? "https" : "http") + "://" url << [:base_url] << path url << ".#{[:format]}" if [:format] return {:url=>url, :params=> params, :method=>[:method]} end |
#revoke_token ⇒ Object
Revokes the given aut Parameters
* api_key
* api_sig
* api_token
210 211 212 213 |
# File 'lib/ruby_desk/connector.rb', line 210 def revoke_token prepare_and_invoke_api_call 'auth/v1/keys/token', :method=>:delete @api_token = nil end |
#sign(params) ⇒ Object
Sign the given parameters and returns the signature
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/ruby_desk/connector.rb', line 29 def sign(params) RubyDesk.logger.debug {"Params to sign: #{params.inspect}"} # sort parameters by its names (keys) sorted_params = params.sort { |a, b| a.to_s <=> b.to_s} RubyDesk.logger.debug {"Sorted params: #{sorted_params.inspect}"} # Unescape escaped params sorted_params.map! do |k, v| [k, URI.unescape(v)] end # concatenate secret with names, values concatenated = @api_secret + sorted_params.join RubyDesk.logger.debug {"concatenated: #{concatenated}"} # Calculate and return md5 of concatenated string md5 = Digest::MD5.hexdigest(concatenated) RubyDesk.logger.debug {"md5: #{md5}"} return md5 end |