dropbox 1.1.1 → 1.1.2
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/.gitignore +1 -0
- data/ChangeLog +12 -0
- data/README.rdoc +5 -0
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/dropbox.gemspec +6 -2
- data/keys.json.example +6 -0
- data/lib/dropbox/session.rb +43 -2
- data/spec/dropbox/session_spec.rb +79 -22
- data/spec/spec_helper.rb +17 -1
- metadata +19 -3
data/.gitignore
CHANGED
data/ChangeLog
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
1.1.2 (2010-10-6)
|
2
|
+
|
3
|
+
* Added ability to perform OAuth authorization on behalf of the user.
|
4
|
+
* Specs now test authorization against actual Dropbox API server.
|
5
|
+
|
6
|
+
1.1.1 (2010-09-22)
|
7
|
+
|
8
|
+
* http-proxy support added.
|
9
|
+
* Session now persists SSL attribute.
|
10
|
+
* Core extensions moved to a namespaced path to prevent conflicts.
|
11
|
+
* Minor bug fixes.
|
12
|
+
|
1
13
|
1.1.0 (2010-05-27)
|
2
14
|
|
3
15
|
* Added thumbnails API method.
|
data/README.rdoc
CHANGED
@@ -75,6 +75,11 @@ account, and then upload a file to their Dropbox.
|
|
75
75
|
|
76
76
|
== Testing Your Code
|
77
77
|
|
78
|
+
The gem is fully specced. Run specs with +rake spec+. Before doing so, you will
|
79
|
+
need to create a file called +keys.json+ in the project root containing your
|
80
|
+
Dropbox API key and secret, as well as the email and password for a Dropbox
|
81
|
+
account. See the +keys.json.example+ file to get started.
|
82
|
+
|
78
83
|
fguillen has implemented a mock of the Dropbox API server:
|
79
84
|
http://github.com/fguillen/DummyDropbox
|
80
85
|
|
data/Rakefile
CHANGED
@@ -17,6 +17,7 @@ begin
|
|
17
17
|
gem.add_runtime_dependency "oauth", ">= 0.3.6"
|
18
18
|
gem.add_runtime_dependency "json", ">= 1.2.0"
|
19
19
|
gem.add_runtime_dependency "multipart-post", ">= 1.0"
|
20
|
+
gem.add_runtime_dependency "mechanize", ">= 1.0.0"
|
20
21
|
end
|
21
22
|
Jeweler::GemcutterTasks.new
|
22
23
|
Jeweler::RubyforgeTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.2
|
data/dropbox.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dropbox}
|
8
|
-
s.version = "1.1.
|
8
|
+
s.version = "1.1.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Tim Morgan"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-10-06}
|
13
13
|
s.description = %q{An easy-to-use client library for the official Dropbox API.}
|
14
14
|
s.email = %q{dropbox@timothymorgan.info}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
"Rakefile",
|
27
27
|
"VERSION",
|
28
28
|
"dropbox.gemspec",
|
29
|
+
"keys.json.example",
|
29
30
|
"lib/dropbox.rb",
|
30
31
|
"lib/dropbox/api.rb",
|
31
32
|
"lib/dropbox/entry.rb",
|
@@ -72,17 +73,20 @@ Gem::Specification.new do |s|
|
|
72
73
|
s.add_runtime_dependency(%q<oauth>, [">= 0.3.6"])
|
73
74
|
s.add_runtime_dependency(%q<json>, [">= 1.2.0"])
|
74
75
|
s.add_runtime_dependency(%q<multipart-post>, [">= 1.0"])
|
76
|
+
s.add_runtime_dependency(%q<mechanize>, [">= 1.0.0"])
|
75
77
|
else
|
76
78
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
77
79
|
s.add_dependency(%q<oauth>, [">= 0.3.6"])
|
78
80
|
s.add_dependency(%q<json>, [">= 1.2.0"])
|
79
81
|
s.add_dependency(%q<multipart-post>, [">= 1.0"])
|
82
|
+
s.add_dependency(%q<mechanize>, [">= 1.0.0"])
|
80
83
|
end
|
81
84
|
else
|
82
85
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
83
86
|
s.add_dependency(%q<oauth>, [">= 0.3.6"])
|
84
87
|
s.add_dependency(%q<json>, [">= 1.2.0"])
|
85
88
|
s.add_dependency(%q<multipart-post>, [">= 1.0"])
|
89
|
+
s.add_dependency(%q<mechanize>, [">= 1.0.0"])
|
86
90
|
end
|
87
91
|
end
|
88
92
|
|
data/keys.json.example
ADDED
data/lib/dropbox/session.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Defines the Dropbox::Session class.
|
2
2
|
|
3
3
|
require 'oauth'
|
4
|
+
require 'mechanize'
|
4
5
|
|
5
6
|
module Dropbox
|
6
7
|
|
@@ -47,6 +48,11 @@ module Dropbox
|
|
47
48
|
|
48
49
|
class Session
|
49
50
|
include API
|
51
|
+
|
52
|
+
# The email of a Dropbox account to automatically authorize.
|
53
|
+
attr_accessor :authorizing_user
|
54
|
+
# The password of a Dropbox account to automatically authorize.
|
55
|
+
attr_accessor :authorizing_password
|
50
56
|
|
51
57
|
# Begins the authorization process. Provide the OAuth key and secret of your
|
52
58
|
# API account, assigned by Dropbox. This is the first step in the
|
@@ -55,9 +61,18 @@ module Dropbox
|
|
55
61
|
# Options:
|
56
62
|
#
|
57
63
|
# +ssl+:: If true, uses SSL to connect to the Dropbox API server.
|
64
|
+
# +authorizing_user+:: The email of a Dropbox account to automatically
|
65
|
+
# authorize.
|
66
|
+
# +authorizing_password+:: The password of a Dropbox account to
|
67
|
+
# automatically authorize.
|
58
68
|
|
59
69
|
def initialize(oauth_key, oauth_secret, options={})
|
60
70
|
@ssl = options[:ssl].to_bool
|
71
|
+
|
72
|
+
# necessary for the automatic authorization in #authorize!
|
73
|
+
@authorizing_user = options[:authorizing_user] if options[:authorizing_user]
|
74
|
+
@authorizing_password = options[:authorizing_password] if options[:authorizing_password]
|
75
|
+
|
61
76
|
@proxy = options[:proxy] || ENV["HTTP_PROXY"] || ENV["http_proxy"]
|
62
77
|
@proxy = nil if options[:noproxy].to_bool
|
63
78
|
@consumer = OAuth::Consumer.new(oauth_key, oauth_secret,
|
@@ -103,6 +118,32 @@ module Dropbox
|
|
103
118
|
def authorized?
|
104
119
|
@access_token.to_bool
|
105
120
|
end
|
121
|
+
|
122
|
+
# Automatically complete the authorization step of the OAuth process. You
|
123
|
+
# must have provided the +authorizing_user+ and +authorizing_password+
|
124
|
+
# options. Raises a Dropbox::UnauthorizedError on failure.
|
125
|
+
|
126
|
+
def authorize!
|
127
|
+
begin
|
128
|
+
a = Mechanize.new
|
129
|
+
a.get(authorize_url) do |page|
|
130
|
+
login_form = page.form_with(:action => '/login')
|
131
|
+
|
132
|
+
login_form.login_email = @authorizing_user
|
133
|
+
login_form.login_password = @authorizing_password
|
134
|
+
auth_page = login_form.submit()
|
135
|
+
|
136
|
+
auth_form = auth_page.form_with(:action => 'authorize')
|
137
|
+
if auth_form
|
138
|
+
auth_button = auth_form.button_with(:value => "Allow")
|
139
|
+
auth_form.click_button
|
140
|
+
end
|
141
|
+
end
|
142
|
+
rescue OAuth::Unauthorized => e
|
143
|
+
raise Dropbox::UnauthorizedError
|
144
|
+
end
|
145
|
+
authorize
|
146
|
+
end
|
106
147
|
|
107
148
|
# Serializes this object into a string that can then be recreated with the
|
108
149
|
# Dropbox::Session.deserialize method.
|
@@ -114,7 +155,7 @@ module Dropbox
|
|
114
155
|
[ @consumer.key, @consumer.secret, authorized?, @request_token.token, @request_token.secret, @ssl ].to_yaml
|
115
156
|
end
|
116
157
|
end
|
117
|
-
|
158
|
+
|
118
159
|
# Deserializes an instance from a string created from the serialize method.
|
119
160
|
# Returns the recreated instance.
|
120
161
|
|
@@ -128,7 +169,7 @@ module Dropbox
|
|
128
169
|
else
|
129
170
|
session.instance_variable_set :@request_token, OAuth::RequestToken.new(session.instance_variable_get(:@consumer), token, token_secret)
|
130
171
|
end
|
131
|
-
|
172
|
+
|
132
173
|
return session
|
133
174
|
end
|
134
175
|
|
@@ -15,7 +15,7 @@ describe Dropbox::Session do
|
|
15
15
|
|
16
16
|
Dropbox::Session.new(key, secret)
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it "should use the SSL host if :ssl => true is given" do
|
20
20
|
key = 'test_key'
|
21
21
|
secret = 'test_secret'
|
@@ -29,7 +29,7 @@ describe Dropbox::Session do
|
|
29
29
|
|
30
30
|
Dropbox::Session.new(key, secret, :ssl => true)
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
it "should create a new OAuth::Consumer" do
|
34
34
|
key = 'test_key'
|
35
35
|
secret = 'test_secret'
|
@@ -117,10 +117,6 @@ describe Dropbox::Session do
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
-
describe "#authorized?" do
|
121
|
-
#TODO this method remains opaque for purposes of testing
|
122
|
-
end
|
123
|
-
|
124
120
|
describe "#serialize" do
|
125
121
|
before :each do
|
126
122
|
@consumer_mock = mock("OAuth::Consumer")
|
@@ -138,7 +134,7 @@ describe Dropbox::Session do
|
|
138
134
|
|
139
135
|
@session.serialize.should eql([ "consumer key", "consumer secret", false, "request token", "request token secret", false ].to_yaml)
|
140
136
|
end
|
141
|
-
|
137
|
+
|
142
138
|
it "should serialize the SSL setting" do
|
143
139
|
@session = Dropbox::Session.new('foo', 'bar', :ssl => true)
|
144
140
|
@consumer_mock.stub!(:key).and_return("consumer key")
|
@@ -148,34 +144,95 @@ describe Dropbox::Session do
|
|
148
144
|
|
149
145
|
@session.serialize.should eql([ "consumer key", "consumer secret", false, "request token", "request token secret", true ].to_yaml)
|
150
146
|
end
|
151
|
-
|
152
|
-
it "should return the consumer key and secret and the access token and secret in YAML form if authorized" do
|
153
|
-
pending "access token is opaque"
|
154
|
-
end
|
155
147
|
end
|
156
148
|
|
157
149
|
describe ".deserialize" do
|
150
|
+
before :each do
|
151
|
+
@mock_session = mock('Dropbox::Session')
|
152
|
+
end
|
153
|
+
|
158
154
|
it "should raise an error if an improper YAML is provided" do
|
159
155
|
lambda { Dropbox::Session.deserialize([ 1, 2, 3].to_yaml) }.should raise_error(ArgumentError)
|
160
156
|
end
|
161
157
|
|
162
158
|
it "should return a properly initialized unauthorized instance" do
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
Dropbox::Session.deserialize([ 'key', 'secret', false, 'a', 'b', true ].to_yaml).should eql(mock_session)
|
159
|
+
Dropbox::Session.should_receive(:new).once.with('key', 'secret', :ssl => true).and_return(@mock_session)
|
160
|
+
|
161
|
+
Dropbox::Session.deserialize([ 'key', 'secret', false, 'a', 'b', true ].to_yaml).should eql(@mock_session)
|
167
162
|
#TODO request token remains opaque for purposes of testing
|
168
163
|
end
|
169
|
-
|
164
|
+
|
170
165
|
it "should allow the SSL option to be left out" do
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
166
|
+
Dropbox::Session.should_receive(:new).once.with('key', 'secret', :ssl => nil).and_return(@mock_session)
|
167
|
+
|
168
|
+
Dropbox::Session.deserialize([ 'key', 'secret', false, 'a', 'b' ].to_yaml).should eql(@mock_session)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "with Dropbox keys " do
|
173
|
+
before(:all) do
|
174
|
+
@keys = read_keys_file
|
175
|
+
end
|
176
|
+
|
177
|
+
def new_session
|
178
|
+
Dropbox::Session.new(@keys['key'], @keys['secret'], :authorizing_user => @keys['email'], :authorizing_password => @keys['password'])
|
179
|
+
end
|
180
|
+
|
181
|
+
describe "#authorized?" do
|
182
|
+
before(:each) do
|
183
|
+
@session = new_session
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should be false for sessions that have not been authorized" do
|
187
|
+
@session.should_not be_authorized
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should be true for sessions that have been authorized" do
|
191
|
+
@session.authorize!
|
192
|
+
@session.should be_authorized
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "#authorize!" do
|
197
|
+
describe "with credentials" do
|
198
|
+
before(:each) do
|
199
|
+
@session = new_session
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should not fail" do
|
203
|
+
lambda { @session.authorize! }.should_not raise_error
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should return the result of #authorize" do
|
207
|
+
@session.should_receive(:authorize).and_return("winner!")
|
208
|
+
@session.authorize!.should == "winner!"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe "with no credentials" do
|
213
|
+
it "should fail" do
|
214
|
+
@session = Dropbox::Session.new(@keys['key'], @keys['password'])
|
215
|
+
lambda { @session.authorize! }.should raise_error
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
describe ".deserialize" do
|
221
|
+
it "should return a properly initialized authorized instance" do
|
222
|
+
@session = new_session
|
223
|
+
@session.authorize!.should be_true
|
224
|
+
@session_clone = Dropbox::Session.deserialize(@session.serialize)
|
225
|
+
|
226
|
+
@session.serialize.should == @session_clone.serialize
|
227
|
+
end
|
175
228
|
end
|
176
229
|
|
177
|
-
|
178
|
-
|
230
|
+
describe "#serialize" do
|
231
|
+
it "should return the consumer key and secret and the access token and secret in YAML form if authorized" do
|
232
|
+
@session = new_session
|
233
|
+
@session.authorize!.should be_true
|
234
|
+
@session.serialize.should eql([ @keys['key'], @keys['secret'], true, @session.send(:access_token).token, @session.send(:access_token).secret, false ].to_yaml)
|
235
|
+
end
|
179
236
|
end
|
180
237
|
end
|
181
238
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,6 +5,22 @@ require 'dropbox.rb'
|
|
5
5
|
require 'spec'
|
6
6
|
require 'spec/autorun'
|
7
7
|
|
8
|
+
module ExternalKeysFileHelper
|
9
|
+
def read_keys_file
|
10
|
+
unless File.exist?('keys.json')
|
11
|
+
raise "Please add a keys.json file to the project directory containing your Dropbox API key and secret. See keys.json.example to get started."
|
12
|
+
end
|
13
|
+
|
14
|
+
keys_file_contents = open("keys.json", "r").read()
|
15
|
+
data = JSON.parse(keys_file_contents)
|
16
|
+
unless %w( key secret email password ).all? { |key| data.include? key }
|
17
|
+
raise "Your keys.json file does contain all the required information. See keys.json.example for more help."
|
18
|
+
end
|
19
|
+
|
20
|
+
data
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
8
24
|
Spec::Runner.configure do |config|
|
9
|
-
|
25
|
+
config.include(ExternalKeysFileHelper)
|
10
26
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 1.1.
|
8
|
+
- 2
|
9
|
+
version: 1.1.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Tim Morgan
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-10-06 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -76,6 +76,21 @@ dependencies:
|
|
76
76
|
version: "1.0"
|
77
77
|
type: :runtime
|
78
78
|
version_requirements: *id004
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: mechanize
|
81
|
+
prerelease: false
|
82
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
segments:
|
88
|
+
- 1
|
89
|
+
- 0
|
90
|
+
- 0
|
91
|
+
version: 1.0.0
|
92
|
+
type: :runtime
|
93
|
+
version_requirements: *id005
|
79
94
|
description: An easy-to-use client library for the official Dropbox API.
|
80
95
|
email: dropbox@timothymorgan.info
|
81
96
|
executables: []
|
@@ -95,6 +110,7 @@ files:
|
|
95
110
|
- Rakefile
|
96
111
|
- VERSION
|
97
112
|
- dropbox.gemspec
|
113
|
+
- keys.json.example
|
98
114
|
- lib/dropbox.rb
|
99
115
|
- lib/dropbox/api.rb
|
100
116
|
- lib/dropbox/entry.rb
|