withings-api 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/.gitignore +9 -0
  2. data/.simplecov +5 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +7 -0
  5. data/README.rdoc +84 -0
  6. data/Rakefile +14 -0
  7. data/cucumber.yml +2 -0
  8. data/examples/callback_landing.txt +1 -0
  9. data/examples/create_access_token.rb +62 -0
  10. data/features/get_access_token.feature +70 -0
  11. data/features/get_request_token.feature +68 -0
  12. data/features/measure_getmeas_api.feature +16 -0
  13. data/features/step_definitions/api.rb +113 -0
  14. data/features/support/method_mocker.rb +36 -0
  15. data/features/support/world.rb +34 -0
  16. data/lib/withings-api.rb +19 -0
  17. data/lib/withings-api/api_actions.rb +27 -0
  18. data/lib/withings-api/api_response.rb +23 -0
  19. data/lib/withings-api/consts.rb +12 -0
  20. data/lib/withings-api/errors.rb +23 -0
  21. data/lib/withings-api/oauth_actions.rb +94 -0
  22. data/lib/withings-api/oauth_base.rb +121 -0
  23. data/lib/withings-api/query_string.rb +16 -0
  24. data/lib/withings-api/results/measure_getmeas_results.rb +73 -0
  25. data/lib/withings-api/tokens.rb +35 -0
  26. data/lib/withings-api/types.rb +108 -0
  27. data/lib/withings-api/utils.rb +14 -0
  28. data/lib/withings-api/version.rb +5 -0
  29. data/spec/api_actions/measure_getmeas_spec.rb +22 -0
  30. data/spec/measure_getmeas_results_spec.rb +124 -0
  31. data/spec/method_aliaser_spec.rb +96 -0
  32. data/spec/query_string_spec.rb +20 -0
  33. data/spec/spec_helper.rb +30 -0
  34. data/spec/tokens_spec.rb +38 -0
  35. data/spec/types/atttribution_type_spec.rb +15 -0
  36. data/spec/types/category_type_spec.rb +15 -0
  37. data/spec/types/device_type_spec.rb +15 -0
  38. data/spec/types/measurement_type_spec.rb +15 -0
  39. data/spec/withings_api_spec.rb +67 -0
  40. data/test/README +1 -0
  41. data/test/helpers/http_stubber.rb +32 -0
  42. data/test/helpers/method_aliaser.rb +48 -0
  43. data/test/helpers/stubbed_withings_api.rb +41 -0
  44. data/test/http_stub_responses/access_token/invalid.txt +10 -0
  45. data/test/http_stub_responses/access_token/success.txt +11 -0
  46. data/test/http_stub_responses/access_token/unauthorized_token.txt +11 -0
  47. data/test/http_stub_responses/authorization_callback/success.txt +9 -0
  48. data/test/http_stub_responses/measure_getmeas/forbidden.txt +12 -0
  49. data/test/http_stub_responses/measure_getmeas/oauth_error.txt +9 -0
  50. data/test/http_stub_responses/measure_getmeas/success.txt +9 -0
  51. data/test/http_stub_responses/request_token/invalid_consumer_credentials.txt +10 -0
  52. data/test/http_stub_responses/request_token/success.txt +11 -0
  53. data/test/sample_json/measure_getmeas.json +49 -0
  54. data/test/sample_json/notify_get.json +7 -0
  55. data/test/sample_json/notify_list.json +15 -0
  56. data/test/sample_json/notify_revoke.json +3 -0
  57. data/test/sample_json/notify_subscribe.json +3 -0
  58. data/test/sample_json/once_probe.json +1 -0
  59. data/test/sample_json/user_getbyuserid.json +16 -0
  60. data/withings-api.gemspec +32 -0
  61. metadata +220 -0
@@ -0,0 +1,9 @@
1
+ /.idea
2
+ /withings-api.iml
3
+ *.gem
4
+ .bundle
5
+ Gemfile.lock
6
+ pkg/*
7
+ /doc
8
+ /.yardoc
9
+ /coverage
@@ -0,0 +1,5 @@
1
+ SimpleCov.configure do
2
+ add_filter "./spec"
3
+ add_filter "./features"
4
+ add_filter "./test"
5
+ end
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in withings-api.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2012 Eric T. Webb
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,84 @@
1
+ withings-api is an easy to use Ruby library providing access to the Withings Body Metrics Services API (WBS API) version 2.
2
+
3
+ For complete details about the WBS API, see http://www.withings.com/en/api/wbsapiv2
4
+
5
+ *NOTE, THIS IS A WORK IN PROGRESS, IMPLEMENTATION ISN'T COMPLETE AS OF VERSION 0.0.1*
6
+
7
+ = Overview
8
+
9
+ For an example use of the withings-api, see {file:examples/create_access_token.rb examples/create_access_token.rb}.
10
+
11
+ Broadly speaking, there are two phases to using the withings-api.
12
+
13
+ 1. Retrieve access to user's data via OAuth authentication + authorization
14
+ * see {file:README.rdoc#OAuth_Authorization OAuth Authorization} section below.
15
+ 1. Retrieve user data via authorized OAuth credentials (called "access token" in this documentation).
16
+ * *NOTE:* This isn't implemented as of version 0.0.1.
17
+
18
+ == OAuth Authorization
19
+
20
+ Before you can access user data via the WBS API, you need to go through a process that allows the user to authorize
21
+ your application's access to their data. This process is handled by a protocol called OAuth 1.0.
22
+
23
+ For details on Withings implementation of OAuth, see {http://www.withings.com/en/api/oauthguide Withings OAuth Guide}.
24
+ For the complete specification of OAuth 1.0, see {http://tools.ietf.org/html/rfc5849}.
25
+
26
+ Broadly, these are the steps to getting access to user data via the API.
27
+
28
+ 1. (One Time) Register you application with Withings - https://oauth.withings.com/en/partner/add
29
+
30
+ * This will give you a "consumer token" and "consumer secret" which is used to identify and authenticate your application
31
+ * Some more information about this step, see {http://www.withings.com/en/api/oauthguide#registration Withings OAuth Guide: Registration}
32
+
33
+ 1. Request a temporary "request token" used to identify your request for OAuth authorization.
34
+
35
+ * Facilitated by {Withings::Api::StaticHelpers#create_request_token}.
36
+
37
+ 1. Using the "request token", redirect the user to Withings to allow them to log in and authorize your access to their data.
38
+
39
+ * Use {Withings::Api::RequestTokenResponse#authorization_url} to get the URL to use.
40
+ * *Note:* this redirect happens outside of withings-api, usually in your webapp.
41
+ * When the user authorizes the request, Withings will redirect the user back to your application:
42
+ * You specify this callback URL in the call to {Withings::Api::StaticHelpers#create_request_token}
43
+
44
+ 1. Request permanent access to the users data with an "access token".
45
+
46
+ * Facilitated by {Withings::Api::StaticHelpers#create_access_token}
47
+
48
+ 1. Now you have permanent credentials to use when making calls that access user data.
49
+
50
+ Once authorized, you can use data access methods for retreiving user Withings data.
51
+
52
+ == Accessing User Data
53
+
54
+ **Implementation and Documentation Pending**
55
+
56
+ = Status
57
+
58
+ withings-api is currently a work in progress. Only support for getting OAuth request and access tokens is supported at this time.
59
+
60
+ == Versions
61
+
62
+ 0.0.1:: Initial public offereing. OAuth request token and access token support only. No data access yet.
63
+
64
+ = License
65
+
66
+ MIT License, see {file:LICENSE}
67
+
68
+ = Thanks
69
+
70
+ Thanks to the following software and tools that inspired and made withings-api possible:
71
+
72
+ - {http://www.withings.com Withings} - for making awesome hardware and making the data easily accessible
73
+ - {https://github.com/oauth/oauth-ruby OAuth Ruby Gem} - for OAuth plumbing and tools
74
+ - {http://rspec.info/ RSpec} - for unit testing
75
+ - {http://cukes.info/ Cucumber} - for integration and acceptance testing
76
+ - {https://github.com/jnicklas/capybara Capybara} - browser automated acceptance testing
77
+
78
+ = Alternatives
79
+
80
+ Don't like withings-api? Patches, changes, and ideas always welcome.
81
+
82
+ You can also try {https://github.com/simplificator/simplificator-withings simplificator-withings}.
83
+
84
+
@@ -0,0 +1,14 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ task :default => [:test]
5
+
6
+ desc "Runs all tests."
7
+ task :test => [:spec] do
8
+
9
+ end
10
+
11
+ RSpec::Core::RakeTask.new do |t|
12
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
13
+ # Put spec opts in a file named .rspec in root
14
+ end
@@ -0,0 +1,2 @@
1
+ ---
2
+ default: --tags ~@live
@@ -0,0 +1 @@
1
+ Successfully redirected by Withings. Return to the examples/create_access_token.rb script and press ENTER to continue.
@@ -0,0 +1,62 @@
1
+ #
2
+ # Example script showing common usage of withings-api
3
+ #
4
+ # This script shows how the steps to gain an access token to access user's data
5
+ # in Withings.
6
+ #
7
+ # see {file:README.rdoc#OAuth_Authorization} for detailed explaination about these steps
8
+ #
9
+
10
+ require 'withings-api'
11
+
12
+ include Withings::Api
13
+
14
+ #
15
+ # Create a ConsumerToken authenticating the reques to your application
16
+ #
17
+ # These credentials are test credentials for DEMONSTRATION ONLY...you should
18
+ # create credentials for you app @ https://oauth.withings.com/partner/add
19
+ #
20
+
21
+ consumer_token = ConsumerToken.new("08943c64c3ccfe86d5edb40c8db6ddbbc43b6f58779c77d2b02454284db7ec",
22
+ "85949316f07fc41346be145fe8fbc18b73f954f280be958033571720510")
23
+ #
24
+ # Issue request to Withings to gain a request token
25
+ #
26
+
27
+ puts "Requesting a request token from Withings..."
28
+
29
+ request_token_response = Withings::Api.create_request_token(consumer_token, "https://raw.github.com/webmonarch/withings-api/master/examples/callback_landing.txt")
30
+ request_token = request_token_response.request_token
31
+
32
+ #
33
+ # Redirect to Withings to authorize access to user data
34
+ #
35
+ # NOTE: You need a Withings account to continue!
36
+ #
37
+
38
+ puts "Retrieved request token!!!"
39
+ puts
40
+ puts "To authorize the request token"
41
+ puts "visit #{request_token_response.authorization_url}..."
42
+ puts
43
+ puts "After logging in and clicking 'Allow'"
44
+ print "Press Enter To Continue: ";
45
+ STDIN.gets;
46
+ puts
47
+
48
+ #
49
+ # Retrieve the permanent access token now that the request token has been authroized.
50
+ #
51
+
52
+ access_token_response = Withings::Api.create_access_token(request_token, consumer_token, "user_id_not_currently_required_by_withings")
53
+
54
+ # store access token values in your database for subsequent access to your data by your application
55
+ access_token = access_token_response.access_token
56
+
57
+ #
58
+ # Success!
59
+ #
60
+
61
+ puts "Success! You've gained access to user_id=#{access_token_response.user_id}"
62
+ puts "OAuth Access Token Key/Secret: #{access_token.key}/#{access_token.secret}"
@@ -0,0 +1,70 @@
1
+ Feature: OAuth access_token Call
2
+
3
+ In order to make authenticated Withings OAuth calls,
4
+ As a user of th withings-api gem,
5
+ I need to be able to request access tokens from a previously retrieved request token.
6
+
7
+ #
8
+ # LIVE
9
+ #
10
+
11
+ @live
12
+ Scenario: Succeeds On Live Withings
13
+ Given the live Withings API
14
+ And a valid request_token from Withings Live
15
+ And authorized access request
16
+ When making an access_token call
17
+ Then the access_token call should succeed
18
+
19
+ @live
20
+ Scenario: Fails Due To Not Authrorized Request Token On Live Withings
21
+ Given the live Withings API
22
+ And a valid request_token from Withings Live
23
+ When making an access_token call
24
+ Then the access_token call should fail
25
+
26
+ @live
27
+ Scenario: Fails Due To Invalid Request Token On Live Withings
28
+ Given the live Withings API
29
+ And a valid consumer token
30
+ And a random request token
31
+ When making an access_token call
32
+ Then the access_token call should fail
33
+
34
+ @live
35
+ Scenario: Fails Due To Invalid Consumer Token On Live Withings
36
+ Given the live Withings API
37
+ And a valid request_token from Withings Live
38
+ And a random consumer token
39
+ When making an access_token call
40
+ Then the access_token call should fail
41
+
42
+ @stubbed
43
+ Scenario: Success On Stubbed Withings
44
+ Given the stubbed Withings API
45
+ And a valid consumer token
46
+ And a valid request token
47
+ And stubbing the HTTP response with access_token/success
48
+ When making an access_token call
49
+ Then the access_token call should succeed
50
+
51
+ @stubbed
52
+ Scenario: Fails With Invalid Stubbed Withings
53
+ Given the stubbed Withings API
54
+ And a valid consumer token
55
+ And a random request token
56
+ And stubbing the HTTP response with access_token/invalid
57
+ When making an access_token call
58
+ Then the access_token call should fail
59
+
60
+ @stubbed
61
+ Scenario: Fails With Unauthorized Stubbed Withings
62
+ Given the stubbed Withings API
63
+ And a valid consumer token
64
+ And a random request token
65
+ And stubbing the HTTP response with access_token/unauthorized_token
66
+ When making an access_token call
67
+ Then the access_token call should fail
68
+
69
+
70
+
@@ -0,0 +1,68 @@
1
+ Feature: OAuth request_token Call
2
+
3
+ In order to make authenticated Withings OAuth calls,
4
+ As a withings-api user,
5
+ I need to be able to get an OAuth request token for subsequent authorization by the Withings user.
6
+
7
+ #
8
+ # LIVE TESTS
9
+ #
10
+
11
+ @live
12
+ Scenario: Succeeds On Live Withings
13
+ Given the live Withings API
14
+ And valid consumer token
15
+ When making a request_token call
16
+ Then the request_token call should succeed
17
+
18
+ @live
19
+ Scenario: Fails With Blank Consumer Credentials On Live Withings
20
+ Given the live Withings API
21
+ And blank consumer token
22
+ When making a request_token call
23
+ Then the request_token call should fail
24
+
25
+ @live
26
+ Scenario: Fails With Random Consumer Credentials On Live Withings
27
+ Given the live Withings API
28
+ And random consumer token consumer token
29
+ When making a request_token call
30
+ Then the request_token call should fail
31
+
32
+ @live
33
+ Scenario: Fails With Invalid Consumer Credentials Secret On Live Withings
34
+ Given the live Withings API
35
+ And invalid_secret consumer token consumer token
36
+ When making a request_token call
37
+ Then the request_token call should fail
38
+
39
+ #
40
+ # STUBBED TESTS
41
+ #
42
+
43
+ @stubbed
44
+ Scenario: Succeeds On Stubbed Withings
45
+ Given the stubbed Withings API
46
+ And valid consumer token
47
+ And stubbing the HTTP response with request_token/success
48
+ When making a request_token call
49
+ Then the request_token call should succeed
50
+ And the request_token key should be "d677dcdefbfe1d00d86fcdc033d9046c76e92e611b6392893923c121b"
51
+ And the request_token secret should be "379667e6b9c1899f678677ef846f498184c577569b664b6181e4422ee77d4d"
52
+
53
+ @stubbed
54
+ Scenario: Fails With Random Consumer Credentials On Stubbed Withings
55
+ Given the stubbed Withings API
56
+ And random consumer token consumer token
57
+ And stubbing the HTTP response with request_token/invalid_consumer_credentials
58
+ When making a request_token call
59
+ Then the request_token call should fail
60
+
61
+ @stubbed
62
+ Scenario: Create Request Token With Random Consumer Credentials
63
+
64
+ @stubbed
65
+ Scenario: Create Request Token And Connection Connect Timeout
66
+
67
+ @stubbed
68
+ Scenario: Create Request Token And Connection Read Timeout
@@ -0,0 +1,16 @@
1
+ Feature: withings-api measure/getmeas API support
2
+
3
+ To make the withings-api implementation complete,
4
+ As a withings-api user,
5
+ I need to be able to make the measure/getmeas call to the Withings API.
6
+
7
+ See: http://www.withings.com/en/api/wbsapiv2#getmeas
8
+
9
+ @stubbed
10
+ Scenario: Successful Request with No Parameters
11
+ Given the stubbed Withings API
12
+ And a valid consumer token
13
+ And a valid access token
14
+ And stubbing the HTTP response with measure_getmeas/success
15
+ When requesting the measure/getmeas API
16
+ Then the measure/getmeas call should succeed
@@ -0,0 +1,113 @@
1
+ require_relative '../../test/helpers/stubbed_withings_api'
2
+
3
+ # holds the API instance we are using to test with
4
+ @api = nil
5
+ @consumer_token = nil
6
+ @request_token = nil
7
+ @request_token_response, @request_token_response_exception = nil
8
+ @access_token, @access_token_exception = nil
9
+
10
+ @api_call_response, @api_call_response_exception = nil
11
+
12
+ Given /^the live Withings API$/ do
13
+ @api = Withings::Api
14
+ end
15
+
16
+ Given /^the stubbed Withings API$/ do
17
+ @api = Withings::StubbeddApi
18
+ end
19
+
20
+ Given /^stubbing the HTTP response with ([^\s]+)$/ do |precanned_response|
21
+ @api.stub_http(precanned_response)
22
+ end
23
+
24
+ Given /^(a )?(valid|random|blank|invalid_secret) consumer token/ do |none, token_type|
25
+ token_type = token_type.to_sym
26
+ CONSUMER_CREDENTIALS.should include(token_type)
27
+
28
+ @consumer_token = CONSUMER_CREDENTIALS[token_type]
29
+ end
30
+
31
+ Given /a valid request_token from Withings Live/ do
32
+ step "valid consumer token"
33
+ step "make a request_token call"
34
+ step "request_token call should succeed"
35
+ end
36
+
37
+ Given /^authorized access request$/ do
38
+ visit @request_token_response.authorization_url
39
+
40
+ user = ACCOUNT_CREDENTIALS[:test_user_1]
41
+ fill_in("email", :with => user[:username])
42
+ fill_in("password", :with => user[:password])
43
+ find("a.button.submit").click
44
+
45
+ find("#accepter").click
46
+ end
47
+
48
+ Given /^(a )?(valid|random) request token$/ do |none, type|
49
+ @request_token = REQUEST_TOKENS[type.to_sym]
50
+ end
51
+
52
+ Given /^a valid access token$/ do
53
+ @access_token = ACCESS_TOKENS[:valid]
54
+ end
55
+
56
+ When /^(make|making) a request_token call$/ do |none|
57
+ result_or_exception(:request_token_response) do
58
+ @api.create_request_token(@consumer_token, "http://example.com")
59
+ end
60
+ end
61
+
62
+ When /^(make|making) an access_token call$/ do |none|
63
+ result_or_exception(:access_token) do
64
+ @api.create_access_token(@request_token, @consumer_token, "666")
65
+ end
66
+ end
67
+
68
+ When /^requesting the measure\/getmeas API$/ do
69
+ result_or_exception(:api_call_response) do
70
+ @api.measure_getmeas({}, @consumer_token, @access_token)
71
+ end
72
+ end
73
+
74
+ Then /^(the )?request_token call should succeed$/ do |none|
75
+ @request_token_response.should be
76
+ @request_token_response.key.should =~ /\w+/
77
+ @request_token_response.secret.should =~ /\w+/
78
+
79
+ @request_token_response_exception.should be_nil
80
+
81
+ @request_token = @request_token_response.request_token
82
+ end
83
+
84
+ Then /^the request_token call should fail$/ do
85
+ @request_token_response_exception.should be
86
+
87
+ @request_token_response.should be_nil
88
+ end
89
+
90
+ Then /^the access_token call should fail$/ do
91
+ @access_token_exception.should be
92
+
93
+ @access_token.should be_nil
94
+ end
95
+
96
+ Then /^the request_token (\w+) should be "(\w+)"$/ do |field, value|
97
+ @request_token_response.send(field).should == value
98
+ end
99
+
100
+ Then /^the access_token call should succeed$/ do
101
+ @access_token.should be
102
+
103
+ @access_token.key.should =~ /\w+/
104
+ @access_token.secret.should =~ /\w+/
105
+ @access_token.user_id.should =~ /\d+/
106
+
107
+ @access_token_exception.should be_nil
108
+ end
109
+
110
+ Then /^the measure\/getmeas call should succeed$/ do
111
+ @api_call_response.should be
112
+ @api_call_response_exception.should_not be
113
+ end