oauth2_rails 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/README.md +28 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/oauth2_rails.rb +16 -0
- data/lib/oauth2_rails/auth.rb +32 -0
- data/lib/oauth2_rails/base.rb +57 -0
- data/lib/oauth2_rails/client.rb +30 -0
- data/lib/oauth2_rails/errors.rb +40 -0
- data/lib/oauth2_rails/fitbit.rb +65 -0
- data/lib/oauth2_rails/response.rb +43 -0
- data/lib/oauth2_rails/user.rb +65 -0
- data/lib/oauth2_rails/version.rb +3 -0
- data/oauth2_rails.gemspec +23 -0
- metadata +103 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: faf99318fa6e905188159c8c8acc3f342dcb45af
|
4
|
+
data.tar.gz: 324ee6e1be1144b814cc16762f77de8e5f2dc57d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: db2340bbe42c9f302c172b959ce73f05f730bdc940b875a58394190cd2fbd716c4898fe8d600d602e4c643baef3911f6350864f01a1569d7eb0aaeefdf024bb7
|
7
|
+
data.tar.gz: f242b72e1e1727a4d57c57e528eabe9b972dca703540565ec2e72bb15a2d1afade4bdd544a0a11bab5390245366ad6645b482b0a6808002ba9248914785767c8
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Oauth2Rails
|
2
|
+
|
3
|
+
A gem that currently provides support for the Fitbit API using Oauth2 protocol.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'oauth2_rails'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install oauth2_rails
|
20
|
+
|
21
|
+
## Contributing
|
22
|
+
One project I would be very interested in is extracting this to a more general framework, that works with most clients on rails. For example, I'm sure the Fitbit flow is a little different, so it would not work always with other providers.
|
23
|
+
|
24
|
+
1. Fork it ( https://github.com/[my-github-username]/oauth2_rails/fork )
|
25
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
26
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
27
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
28
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "oauth2_rails"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/lib/oauth2_rails.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'oauth2_rails/version'
|
2
|
+
require 'oauth2_rails/base'
|
3
|
+
require 'oauth2_rails/auth'
|
4
|
+
require 'oauth2_rails/errors'
|
5
|
+
require 'oauth2_rails/fitbit'
|
6
|
+
require 'oauth2_rails/response'
|
7
|
+
require 'oauth2_rails/user'
|
8
|
+
require 'faraday'
|
9
|
+
require 'base64'
|
10
|
+
|
11
|
+
module Oauth2Rails
|
12
|
+
extend self
|
13
|
+
def new(user, options = {})
|
14
|
+
Client.new(user, options = {})
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'oauth2_rails/base'
|
2
|
+
|
3
|
+
module Oauth2Rails
|
4
|
+
class Auth < Base
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
@state = options[:state]
|
8
|
+
super(options)
|
9
|
+
end
|
10
|
+
|
11
|
+
# SAMPLE AUTHORIZATION REQUEST
|
12
|
+
# GET: https://www.fitbit.com/oauth2/authorize?response_type=code&client_id=22942C&
|
13
|
+
# redirect_uri=http%3A%2F%2Fexample.com%2Fcallback&
|
14
|
+
# scope=activity%20nutrition%20heartrate
|
15
|
+
def authorize_url
|
16
|
+
body = { response_type: 'code', client_id: @oauth_id, redirect_uri: @redirect_uri, scope: @scope, state: @state }
|
17
|
+
connection(@authorize_site).build_url(@authorize_path, body).to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
# SAMPLE POST REQUEST
|
21
|
+
# POST: https://api.fitbit.com/oauth2/token
|
22
|
+
# BODY: client_id=22942C&grant_type=authorization_code&redirect_uri=http%3A%2F%2Fexample.com%2Fcallback&code=1234567890
|
23
|
+
# HEADERS: Authorization: Basic Y2xpZW50X2lkOmNsaWVudCBzZWNyZXQ=
|
24
|
+
# Content-Type: application/x-www-form-urlencoded
|
25
|
+
def get_token(code)
|
26
|
+
body = { grant_type: 'authorization_code', client_id: @oauth_id, redirect_uri: @redirect_uri, code: code }
|
27
|
+
tokens = call(:post, @token_path, body: body)
|
28
|
+
User.new(tokens.json_body)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'oauth2_rails/errors'
|
2
|
+
|
3
|
+
module Oauth2Rails
|
4
|
+
class Base
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
@oauth_id = options[:oauth_id] || OAUTH2_RAILS_ID
|
8
|
+
@oauth_secret = options[:oauth_secret] || OAUTH2_RAILS_SECRET
|
9
|
+
@redirect_uri = options[:redirect_uri] || 'http://localhost:3000/oauth2_callbacks/fitbit'
|
10
|
+
@authorize_site = options[:authorize_site] || 'https://www.fitbit.com'
|
11
|
+
@authorize_path = options[:authorize_path] || '/oauth2/authorize'
|
12
|
+
@api_site = options[:api_site] || 'https://api.fitbit.com'
|
13
|
+
@token_path = options[:token_path] || '/oauth2/token'
|
14
|
+
@scope = options[:scope] || 'heartrate'
|
15
|
+
end
|
16
|
+
|
17
|
+
def connection(url)
|
18
|
+
Faraday.new(url: url) do |faraday|
|
19
|
+
faraday.request :url_encoded
|
20
|
+
faraday.response :logger
|
21
|
+
faraday.adapter Faraday.default_adapter
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def call(action, destination, options = {})
|
26
|
+
user = options[:user]
|
27
|
+
site = options[:site] || @api_site
|
28
|
+
|
29
|
+
if user
|
30
|
+
auth_header = "Bearer #{user}"
|
31
|
+
else
|
32
|
+
encoded = Base64.strict_encode64("#{@oauth_id}:#{@oauth_secret}")
|
33
|
+
auth_header = "Basic #{encoded}"
|
34
|
+
end
|
35
|
+
|
36
|
+
call = connection(site).send(action) do |req|
|
37
|
+
req.url destination
|
38
|
+
req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
39
|
+
req.headers['Authorization'] = auth_header
|
40
|
+
req.body = options[:body]
|
41
|
+
end
|
42
|
+
|
43
|
+
response = Response.new(call)
|
44
|
+
case response.status
|
45
|
+
when 400 ; raise Oauth2Rails::Errors::BadRequest, "400 #{response.error_message}"
|
46
|
+
when 404 ; raise Oauth2Rails::Errors::NotFound, "404 #{response.error_message}"
|
47
|
+
when 409 ; raise Oauth2Rails::Errors::Conflict, "409 #{response.error_message}"
|
48
|
+
when 500 ; raise Oauth2Rails::Errors::InternalServer, "500 #{response.error_message}"
|
49
|
+
when 502 ; raise Oauth2Rails::Errors::BadGateway, "502 #{response.error_message}"
|
50
|
+
when 401 ; raise Oauth2Rails::Errors::Unauthorized, "401 #{response.error_message}"
|
51
|
+
else ; response
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'oauth2_rails/base'
|
2
|
+
require 'oauth2_rails/user'
|
3
|
+
|
4
|
+
module Oauth2Rails
|
5
|
+
class Client < Base
|
6
|
+
|
7
|
+
def initialize(user, options = {})
|
8
|
+
super(options)
|
9
|
+
@user = user
|
10
|
+
end
|
11
|
+
|
12
|
+
def api_call(destination)
|
13
|
+
begin
|
14
|
+
call(:get, destination, user: @user.access_token)
|
15
|
+
rescue Oauth2Rails::Errors::Unauthorized
|
16
|
+
refresh
|
17
|
+
call(:get, destination, user: @user.access_token)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def refresh
|
22
|
+
response = call(:post, "#{@token_path}?grant_type=refresh_token&refresh_token=#{@user.refresh_token}")
|
23
|
+
@user.update!(
|
24
|
+
access_token: response.access_token, refresh_token: response.refresh_token,
|
25
|
+
expiry: Time.now + response.expires_every
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Oauth2Rails
|
2
|
+
module Errors
|
3
|
+
# 400 Bad Request | Any case where either endpoint doesn't exist,
|
4
|
+
# | resource path parameters are invalid, POST request
|
5
|
+
# | parameters are invalid or no Authentication header provided.
|
6
|
+
# | This doesn't include invalid specific resource ids
|
7
|
+
# 401 Unauthorized | The OAuth Authorization header provided and is invalid
|
8
|
+
# | (consider looking in response body). Client or authorized
|
9
|
+
# | user have no privilege to view requested data (for example,
|
10
|
+
# | requested resource's owner has privacy permission "You" or "Friends"
|
11
|
+
# | for requested resource)
|
12
|
+
# 404 Not Found | The resource with given id doesn't exist
|
13
|
+
# 409 Conflict | Either you hit the rate limiting quota for the client or
|
14
|
+
# | for the viewer, or you trying to create conflicting resources (consider looking at errorType)
|
15
|
+
# 500 Internal Error | Something is terribly wrong on our side (and we are working on it). Try your request later
|
16
|
+
# 502 Bad Gateway | We will be back soon. Maintenance!
|
17
|
+
|
18
|
+
class BadRequest < StandardError
|
19
|
+
end
|
20
|
+
|
21
|
+
class Unauthorized < StandardError
|
22
|
+
end
|
23
|
+
|
24
|
+
class NotFound < StandardError
|
25
|
+
end
|
26
|
+
|
27
|
+
class Conflict < StandardError
|
28
|
+
end
|
29
|
+
|
30
|
+
class InternalServer < StandardError
|
31
|
+
end
|
32
|
+
|
33
|
+
class BadGateway < StandardError
|
34
|
+
end
|
35
|
+
|
36
|
+
class InvalidArgument < StandardError
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'oauth2_rails/base'
|
2
|
+
require 'oauth2_rails/client'
|
3
|
+
require 'oauth2_rails/user'
|
4
|
+
|
5
|
+
module Oauth2Rails
|
6
|
+
class Fitbit < Client
|
7
|
+
## => PROFILE
|
8
|
+
# https://api.fitbit.com/1/user/-/profile.json
|
9
|
+
def profile
|
10
|
+
Profile.new(api_call('/1/user/-/profile.json').json_body)
|
11
|
+
end
|
12
|
+
|
13
|
+
def raw_profile
|
14
|
+
api_call('/1/user/-/profile.json')
|
15
|
+
end
|
16
|
+
|
17
|
+
## => HEART DATA
|
18
|
+
# https://api.fitbit.com/1/user/-/activities/heart/date/today/1d.json
|
19
|
+
def daily_heart(start_date)
|
20
|
+
api_call("/1/user/-/activities/heart/date/#{start_date}/1d.json")
|
21
|
+
end
|
22
|
+
|
23
|
+
# https://api.fitbit.com/1/user/-/activities/heart/date/2015-05-07/1d/1sec/time/12:20/12:45.json
|
24
|
+
def minute_heart(days, seconds, start_date, start_time, end_time)
|
25
|
+
api_call("/1/user/-/activities/heart/date/#{start_date}/#{days}d/#{seconds}sec/time/#{start_time}/#{end_time}.json")
|
26
|
+
end
|
27
|
+
|
28
|
+
## => SLEEP DATA
|
29
|
+
# Simple get sleep
|
30
|
+
def sleep(date)
|
31
|
+
api_call("/1/user/-/sleep/date/#{date}.json")
|
32
|
+
end
|
33
|
+
|
34
|
+
# Sleep time series
|
35
|
+
# /1/user/-/sleep/minutesAsleep/date/today/2010-08-27.json
|
36
|
+
# sleep/startTime ; sleep/timeInBed ; sleep/minutesAsleep
|
37
|
+
# sleep/awakeningsCount ; sleep/minutesAwake ; sleep/minutesToFallAsleep
|
38
|
+
# sleep/minutesAfterWakeup ; sleep/efficiency
|
39
|
+
def time_asleep(start_date, end_date)
|
40
|
+
api_call("/1/user/-/sleep/minutesAsleep/date/#{start_date}/#{end_date}.json")
|
41
|
+
end
|
42
|
+
|
43
|
+
def sleep_start(start_date, end_date)
|
44
|
+
api_call("/1/user/-/sleep/startTime/date/#{start_date}/#{end_date}.json")
|
45
|
+
end
|
46
|
+
|
47
|
+
def sleep_efficiency(start_date, end_date)
|
48
|
+
api_call("/1/user/-/sleep/efficiency/date/#{start_date}/#{end_date}.json")
|
49
|
+
end
|
50
|
+
|
51
|
+
def sleep_total_time(start_date, end_date)
|
52
|
+
api_call("/1/user/-/sleep/minutesAsleep/date/#{start_date}/#{end_date}.json")
|
53
|
+
end
|
54
|
+
|
55
|
+
## => BODY INFORMATION
|
56
|
+
def body_weight(date)
|
57
|
+
api_call("/1/user/-/body/log/weight/date/#{date}.json")
|
58
|
+
end
|
59
|
+
|
60
|
+
## => ACTIVITIES
|
61
|
+
def recent_activites
|
62
|
+
api_call("/1/user/-/activities/recent.json")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Oauth2Rails
|
4
|
+
class Response
|
5
|
+
|
6
|
+
def initialize(response)
|
7
|
+
@far_resp = response
|
8
|
+
end
|
9
|
+
|
10
|
+
def status
|
11
|
+
@far_resp.status
|
12
|
+
end
|
13
|
+
|
14
|
+
def headers
|
15
|
+
@far_resp.headers
|
16
|
+
end
|
17
|
+
|
18
|
+
def body
|
19
|
+
@far_resp.body
|
20
|
+
end
|
21
|
+
|
22
|
+
def json_body
|
23
|
+
JSON.parse @far_resp.body
|
24
|
+
end
|
25
|
+
|
26
|
+
def errors
|
27
|
+
json_body['errors'][0] if status != 200
|
28
|
+
end
|
29
|
+
|
30
|
+
def error_message
|
31
|
+
errors['message'] if errors
|
32
|
+
end
|
33
|
+
|
34
|
+
def refresh_token
|
35
|
+
json_body['access_token']
|
36
|
+
end
|
37
|
+
|
38
|
+
def access_token
|
39
|
+
json_body['access_token']
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Oauth2Rails
|
2
|
+
class Profile
|
3
|
+
def initialize(profile)
|
4
|
+
@profile = profile
|
5
|
+
end
|
6
|
+
|
7
|
+
def json_response
|
8
|
+
@profile
|
9
|
+
end
|
10
|
+
|
11
|
+
def id
|
12
|
+
@profile['user']['encodedId']
|
13
|
+
end
|
14
|
+
|
15
|
+
def full_name
|
16
|
+
@profile['user']['fullName']
|
17
|
+
end
|
18
|
+
|
19
|
+
def display_name
|
20
|
+
@profile['user']['displayName']
|
21
|
+
end
|
22
|
+
|
23
|
+
def country
|
24
|
+
@profile['user']['country']
|
25
|
+
end
|
26
|
+
|
27
|
+
def state
|
28
|
+
@profile['user']['state']
|
29
|
+
end
|
30
|
+
|
31
|
+
def city
|
32
|
+
@profile['user']['city']
|
33
|
+
end
|
34
|
+
|
35
|
+
def about_me
|
36
|
+
@profile['user']['aboutMe']
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class User
|
41
|
+
def initialize(auth)
|
42
|
+
@token = auth
|
43
|
+
end
|
44
|
+
|
45
|
+
def json_response
|
46
|
+
@token
|
47
|
+
end
|
48
|
+
|
49
|
+
def id
|
50
|
+
@token['user_id']
|
51
|
+
end
|
52
|
+
|
53
|
+
def access_token
|
54
|
+
@token['access_token']
|
55
|
+
end
|
56
|
+
|
57
|
+
def refresh_token
|
58
|
+
@token['refresh_token']
|
59
|
+
end
|
60
|
+
|
61
|
+
def expires_every
|
62
|
+
@token['expires_in']
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'oauth2_rails/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "oauth2_rails"
|
8
|
+
spec.version = Oauth2Rails::VERSION
|
9
|
+
spec.authors = ["Colin Walker"]
|
10
|
+
spec.email = ["cjwalker@sfu.ca"]
|
11
|
+
|
12
|
+
spec.summary = %q{Oauth2 Rails based client for Fitbit specifically.}
|
13
|
+
spec.homepage = "https://github.com/ColDog/oauth2-fitbit-rails"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
+
spec.bindir = "exe"
|
17
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "faraday", ">= 0.7.0"
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oauth2_rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Colin Walker
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.7.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.7.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.9'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- cjwalker@sfu.ca
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".rspec"
|
64
|
+
- ".travis.yml"
|
65
|
+
- Gemfile
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- bin/console
|
69
|
+
- bin/setup
|
70
|
+
- lib/oauth2_rails.rb
|
71
|
+
- lib/oauth2_rails/auth.rb
|
72
|
+
- lib/oauth2_rails/base.rb
|
73
|
+
- lib/oauth2_rails/client.rb
|
74
|
+
- lib/oauth2_rails/errors.rb
|
75
|
+
- lib/oauth2_rails/fitbit.rb
|
76
|
+
- lib/oauth2_rails/response.rb
|
77
|
+
- lib/oauth2_rails/user.rb
|
78
|
+
- lib/oauth2_rails/version.rb
|
79
|
+
- oauth2_rails.gemspec
|
80
|
+
homepage: https://github.com/ColDog/oauth2-fitbit-rails
|
81
|
+
licenses: []
|
82
|
+
metadata: {}
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 2.4.6
|
100
|
+
signing_key:
|
101
|
+
specification_version: 4
|
102
|
+
summary: Oauth2 Rails based client for Fitbit specifically.
|
103
|
+
test_files: []
|