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 CHANGED
@@ -23,3 +23,4 @@ pkg
23
23
  .rvmrc
24
24
 
25
25
  ## PROJECT::SPECIFIC
26
+ keys.json
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.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.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-09-22}
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
@@ -0,0 +1,6 @@
1
+ {
2
+ "key": "abc123456789012",
3
+ "secret": "abc123456789012",
4
+ "email": "my@email.com",
5
+ "password": "mypassword123"
6
+ }
@@ -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
- mock_session = mock('Dropbox::Session')
164
- Dropbox::Session.should_receive(:new).once.with('key', 'secret', :ssl => true).and_return(mock_session)
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
- mock_session = mock('Dropbox::Session')
172
- Dropbox::Session.should_receive(:new).once.with('key', 'secret', :ssl => nil).and_return(mock_session)
173
-
174
- Dropbox::Session.deserialize([ 'key', 'secret', false, 'a', 'b' ].to_yaml).should eql(mock_session)
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
- it "should return a properly initialized authorized instance" do
178
- pending "access token remains opaque for purposes of testing"
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
- - 1
9
- version: 1.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-09-22 00:00:00 -07:00
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