Module: Dropbox

Defined in:
lib/dropbox_sdk.rb

Overview

:nodoc:

Constant Summary collapse

API_SERVER =
"api.dropboxapi.com"
API_CONTENT_SERVER =
"content.dropboxapi.com"
API_NOTIFY_SERVER =
"notify.dropboxapi.com"
WEB_SERVER =
"www.dropbox.com"
SERVERS =
{
  :api => API_SERVER,
  :content => API_CONTENT_SERVER,
  :notify => API_NOTIFY_SERVER,
  :web => WEB_SERVER
}
API_VERSION =
1
SDK_VERSION =
"1.6.5"
TRUSTED_CERT_FILE =
File.join(File.dirname(__FILE__), 'trusted-certs.crt')

Class Method Summary collapse

Class Method Details

.clean_params(params) ⇒ Object



28
29
30
31
32
33
34
# File 'lib/dropbox_sdk.rb', line 28

def self.clean_params(params)
  r = {}
  params.each do |k, v|
    r[k] = v.to_s if not v.nil?
  end
  r
end

.do_http(uri, request) ⇒ Object

:nodoc:



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
# File 'lib/dropbox_sdk.rb', line 42

def self.do_http(uri, request) # :nodoc:

  http = Net::HTTP.new(uri.host, uri.port)

  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
  http.ca_file = Dropbox::TRUSTED_CERT_FILE
  http.read_timeout = 600

  if RUBY_VERSION >= '1.9'
    # SSL protocol and ciphersuite settings are supported strating with version 1.9
    http.ssl_version = 'TLSv1'
    http.ciphers = 'ECDHE-RSA-AES256-GCM-SHA384:'\
      'ECDHE-RSA-AES256-SHA384:'\
      'ECDHE-RSA-AES256-SHA:'\
      'ECDHE-RSA-AES128-GCM-SHA256:'\
      'ECDHE-RSA-AES128-SHA256:'\
      'ECDHE-RSA-AES128-SHA:'\
      'ECDHE-RSA-RC4-SHA:'\
      'DHE-RSA-AES256-GCM-SHA384:'\
      'DHE-RSA-AES256-SHA256:'\
      'DHE-RSA-AES256-SHA:'\
      'DHE-RSA-AES128-GCM-SHA256:'\
      'DHE-RSA-AES128-SHA256:'\
      'DHE-RSA-AES128-SHA:'\
      'AES256-GCM-SHA384:'\
      'AES256-SHA256:'\
      'AES256-SHA:'\
      'AES128-GCM-SHA256:'\
      'AES128-SHA256:'\
      'AES128-SHA'
  end

  # Important security note!
  # Some Ruby versions (e.g. the one that ships with OS X) do not raise
  # an exception if certificate validation fails. We therefore have to
  # add a custom callback to ensure that invalid certs are not accepted.
  # Some specific error codes are let through, so we change the error
  # code to make sure that Ruby throws an exception if certificate
  # validation fails.
  #
  # See the man page for 'verify' for more information on error codes.
  #
  # You can comment out this code if your Ruby version is not vulnerable.
  http.verify_callback = proc do |preverify_ok, ssl_context|
    # 0 is the error code for success
    if preverify_ok && ssl_context.error == 0
      true
    else
      # 7 is the error code for certification signature failure
      ssl_context.error = 7
      false
    end
  end

  #We use this to better understand how developers are using our SDKs.
  request['User-Agent'] =  "OfficialDropboxRubySDK/#{Dropbox::SDK_VERSION}"

  begin
    http.request(request)
  rescue OpenSSL::SSL::SSLError => e
    raise DropboxError.new("SSL error connecting to Dropbox.  " +
                           "There may be a problem with the set of certificates in \"#{Dropbox::TRUSTED_CERT_FILE}\".  #{e.message}")
  end
end

.make_query_string(params) ⇒ Object



36
37
38
39
40
# File 'lib/dropbox_sdk.rb', line 36

def self.make_query_string(params)
  clean_params(params).collect {|k, v|
    CGI.escape(k) + "=" + CGI.escape(v)
  }.join("&")
end

.parse_response(response, raw = false) ⇒ Object

Parse response. You probably shouldn’t be calling this directly. This takes responses from the server and parses them. It also checks for errors and raises exceptions with the appropriate messages.



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/dropbox_sdk.rb', line 110

def self.parse_response(response, raw=false) # :nodoc:
  if response.is_a?(Net::HTTPServerError)
    raise DropboxError.new("Dropbox Server Error: #{response} - #{response.body}", response)
  elsif response.is_a?(Net::HTTPUnauthorized)
    raise DropboxAuthError.new("User is not authenticated.", response)
  elsif !response.is_a?(Net::HTTPSuccess)
    begin
      d = JSON.parse(response.body)
    rescue
      raise DropboxError.new("Dropbox Server Error: body=#{response.body}", response)
    end
    if d['user_error'] and d['error']
      raise DropboxError.new(d['error'], response, d['user_error'])  #user_error is translated
    elsif d['error']
      raise DropboxError.new(d['error'], response)
    else
      raise DropboxError.new(response.body, response)
    end
  end

  return response.body if raw

  begin
    return JSON.parse(response.body)
  rescue JSON::ParserError
    raise DropboxError.new("Unable to parse JSON response: #{response.body}", response)
  end
end

.safe_string_equals(a, b) ⇒ Object

A string comparison function that is resistant to timing attacks. The time it takes to run will leak the length of the secret string, but not any of the character values.



141
142
143
144
145
146
147
# File 'lib/dropbox_sdk.rb', line 141

def self.safe_string_equals(a, b)
  if a.length != b.length
    false
  else
    a.chars.zip(b.chars).map {|ac,bc| ac == bc}.reduce(true, :&)
  end
end