omniauth-oauthio 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1dca97fafd16386f51832f166b84c5cf621d0bc3
4
+ data.tar.gz: 6a4e6e04a937c70cfcd1d80ede2ee635d6bc222d
5
+ SHA512:
6
+ metadata.gz: 149abd7e8dbdb2a5cee853f596dc982b4ad26ced924d7b2a1852d8022bdee921aae34e6d0f237691b539d42b6b761cebfc64b712bd1abc22c909a77ad42fc9ea
7
+ data.tar.gz: 6db1a1e393399688ec32e1036394658d7e2554ae81805cbad6de147fa1187dd590c63676f7a35a15e9f8f09de2ad2aefa36467678022d74633499f8cb036d67a
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ *.gem
2
+ .bundle
3
+ .rspec
4
+ /Gemfile.lock
5
+ pkg/*
6
+ .powenv
7
+ tmp
8
+ bin
9
+ .idea
10
+ *.iml
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ platforms :rbx do
6
+ gem 'rubysl', '~> 2.0'
7
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Jonathan Rowlands
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,118 @@
1
+ omniauth-oauthio
2
+ =================
3
+
4
+ OAuth.io Strategy for OmniAuth
5
+
6
+ # TODO
7
+
8
+ Please note this strategy is still pretty experimental and is not complete
9
+
10
+ 1. I am using this mainly with a pure javascript/angularjs single page application that connects to a rails api, but
11
+ there is no reason why this potentially work with a normal rails application that takes does not require javascript.
12
+ I believe there is some missing functionality there and requires further testing.
13
+
14
+ ## Installing
15
+
16
+ Add to your `Gemfile`:
17
+
18
+ ```ruby
19
+ gem 'omniauth-oauthio', path: 'https://github.com/jgrowl/omniauth-oauthio.git'
20
+ ```
21
+
22
+ Then `bundle install`.
23
+
24
+ ## Usage
25
+
26
+ `OmniAuth::Strategies::Oauthio` is simply a Rack middleware. Read the OmniAuth docs for detailed instructions: https://github.com/intridea/omniauth.
27
+
28
+ Here's a quick example, adding the middleware to a Rails app in `config/initializers/omniauth.rb`:
29
+
30
+ ```ruby
31
+ Rails.application.config.middleware.use OmniAuth::Builder do
32
+ configure do |config|
33
+ config.path_prefix = '/users/auth'
34
+ end
35
+ end
36
+ ```
37
+
38
+ The following steps on the front-end need to occur:
39
+
40
+ 1. Initialize the OAuth public key.
41
+
42
+ 2. Perform get request to initiate the request_phase, using the .json option for SPA (This is to get a state string from the server).
43
+
44
+ 3. Use OAuth.io's javascript api to initiate a popup (Passing along the state from step 2).
45
+
46
+ 4. Perform get request to initiate callback_phase (Passing along the state and code received in step 3).
47
+
48
+ For example: (NOTE: I need to update this. I am currently using dart in my test app)
49
+
50
+ ```coffeescript
51
+ OAuth.initialize('YOUR_PUBLIC_KEY')
52
+
53
+ $.get "http://localhost:3000/users/auth/oauthio.json", (data) ->
54
+ @options = data
55
+
56
+ OAuth.popup provider, @options, (err, res) ->
57
+ if (err)
58
+ console.log err
59
+ else
60
+ $.get "http://localhost:3000/users/auth/oauthio/twitter/callback.json?state=@options.state&code=@options.code", (data) ->
61
+ console.log(data)
62
+ # Perform additional login steps
63
+ ```
64
+
65
+ ## Configuring
66
+
67
+ ### OAuth.io
68
+
69
+ Be sure to enable the Server-side (code) option on any providers you want to use with this strategy.
70
+
71
+ ### Custom Callback URL/Path
72
+
73
+ You can set a custom `callback_url` or `callback_path` option to override the default value. See [OmniAuth::Strategy#callback_url](https://github.com/intridea/omniauth/blob/master/lib/omniauth/strategy.rb#L411) for more details on the default.
74
+
75
+ ### Devise
76
+ To use with devise, in `config/initializers/devise.rb`
77
+
78
+ ```ruby
79
+ config.omniauth :oauthio, ENV['OAUTHIO_PUBLIC_KEY'], ENV['OAUTHIO_SECRET_KEY']
80
+ ```
81
+
82
+ ### Omniauth
83
+
84
+ Add an oauthio callback in `app/controllers/users/omniauth_callbacks_controller.rb`
85
+
86
+ ```ruby
87
+
88
+ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
89
+ def oauthio
90
+
91
+ # TODO: Do your login logic here! ie. look up the user by the uid or create one if it does not already exist!
92
+
93
+ respond_to do |format|
94
+ format.json { render json: auth_hash}
95
+ end
96
+ end
97
+
98
+ def auth_hash
99
+ request.env['omniauth.auth']
100
+ end
101
+
102
+ end
103
+ ```
104
+
105
+ Create the method used in your callback in your `user.rb`
106
+
107
+ # Understanding server side flow
108
+
109
+ oauth.io describes how everything works in their [security](https://oauth.io/docs/security) section.
110
+
111
+ ![alt text](https://oauth.io/img/server-side-flow.png "Server side flow")
112
+
113
+
114
+ ## Credit
115
+
116
+ https://oauth.io/
117
+
118
+ https://github.com/mkdynamic/omniauth-facebook
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |task|
5
+ task.libs << 'test'
6
+ end
7
+
8
+ task :default => :test
data/example/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'sinatra'
4
+ gem 'omniauth-oauthio', :path => '../'
@@ -0,0 +1,44 @@
1
+ PATH
2
+ remote: ../
3
+ specs:
4
+ omniauth-facebook (1.6.0.rc1)
5
+ omniauth-oauth2 (~> 1.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ faraday (0.8.8)
11
+ multipart-post (~> 1.2.0)
12
+ hashie (2.0.5)
13
+ httpauth (0.2.0)
14
+ jwt (0.1.8)
15
+ multi_json (>= 1.5)
16
+ multi_json (1.8.2)
17
+ multipart-post (1.2.0)
18
+ oauth2 (0.8.1)
19
+ faraday (~> 0.8)
20
+ httpauth (~> 0.1)
21
+ jwt (~> 0.1.4)
22
+ multi_json (~> 1.0)
23
+ rack (~> 1.2)
24
+ omniauth (1.1.4)
25
+ hashie (>= 1.2, < 3)
26
+ rack
27
+ omniauth-oauth2 (1.1.1)
28
+ oauth2 (~> 0.8.0)
29
+ omniauth (~> 1.0)
30
+ rack (1.5.2)
31
+ rack-protection (1.5.1)
32
+ rack
33
+ sinatra (1.4.4)
34
+ rack (~> 1.4)
35
+ rack-protection (~> 1.4)
36
+ tilt (~> 1.3, >= 1.3.4)
37
+ tilt (1.4.1)
38
+
39
+ PLATFORMS
40
+ ruby
41
+
42
+ DEPENDENCIES
43
+ omniauth-facebook!
44
+ sinatra
data/example/config.ru ADDED
@@ -0,0 +1,110 @@
1
+ require 'bundler/setup'
2
+ require 'sinatra/base'
3
+ require 'omniauth-oauthio'
4
+
5
+ #SCOPE = 'email,read_stream'
6
+ #
7
+ #class App < Sinatra::Base
8
+ # # turn off sinatra default X-Frame-Options for FB canvas
9
+ # set :protection, :except => :frame_options
10
+ #
11
+ # # server-side flow
12
+ # get '/' do
13
+ # # NOTE: you would just hit this endpoint directly from the browser
14
+ # # in a real app. the redirect is just here to setup the root
15
+ # # path in this example sinatra app.
16
+ # redirect '/auth/facebook'
17
+ # end
18
+ #
19
+ # # client-side flow
20
+ # get '/client-side' do
21
+ # content_type 'text/html'
22
+ # # NOTE: when you enable cookie below in the FB.init call
23
+ # # the GET request in the FB.login callback will send
24
+ # # a signed request in a cookie back the OmniAuth callback
25
+ # # which will parse out the authorization code and obtain
26
+ # # the access_token. This will be the exact same access_token
27
+ # # returned to the client in response.authResponse.accessToken.
28
+ # <<-END
29
+ # <html>
30
+ # <head>
31
+ # <title>Client-side Flow Example</title>
32
+ # <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js" type="text/javascript"></script>
33
+ # </head>
34
+ # <body>
35
+ # <div id="fb-root"></div>
36
+ #
37
+ # <script type="text/javascript">
38
+ # window.fbAsyncInit = function() {
39
+ # FB.init({
40
+ # appId : '#{ENV['APP_ID']}',
41
+ # status : true, // check login status
42
+ # cookie : true, // enable cookies to allow the server to access the session
43
+ # xfbml : true // parse XFBML
44
+ # });
45
+ # };
46
+ #
47
+ # (function(d) {
48
+ # var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
49
+ # js = d.createElement('script'); js.id = id; js.async = true;
50
+ # js.src = "//connect.facebook.net/en_US/all.js";
51
+ # d.getElementsByTagName('head')[0].appendChild(js);
52
+ # }(document));
53
+ #
54
+ # $(function() {
55
+ # $('a').click(function(e) {
56
+ # e.preventDefault();
57
+ #
58
+ # FB.login(function(response) {
59
+ # if (response.authResponse) {
60
+ # $('#connect').html('Connected! Hitting OmniAuth callback (GET /auth/facebook/callback)...');
61
+ #
62
+ # // since we have cookies enabled, this request will allow omniauth to parse
63
+ # // out the auth code from the signed request in the fbsr_XXX cookie
64
+ # $.getJSON('/auth/facebook/callback', function(json) {
65
+ # $('#connect').html('Connected! Callback complete.');
66
+ # $('#results').html(JSON.stringify(json));
67
+ # });
68
+ # }
69
+ # }, { scope: '#{SCOPE}' });
70
+ # });
71
+ # });
72
+ # </script>
73
+ #
74
+ # <p id="connect">
75
+ # <a href="#">Connect to FB</a>
76
+ # </p>
77
+ #
78
+ # <p id="results" />
79
+ # </body>
80
+ # </html>
81
+ # END
82
+ # end
83
+ #
84
+ # # auth via FB canvas and signed request param
85
+ # post '/canvas/' do
86
+ # # we just redirect to /auth/facebook here which will parse the
87
+ # # signed_request FB sends us, asking for auth if the user has
88
+ # # not already granted access, or simply moving straight to the
89
+ # # callback where they have already granted access.
90
+ # redirect "/auth/facebook?signed_request=#{request.params['signed_request']}"
91
+ # end
92
+ #
93
+ # get '/auth/:provider/callback' do
94
+ # content_type 'application/json'
95
+ # MultiJson.encode(request.env)
96
+ # end
97
+ #
98
+ # get '/auth/failure' do
99
+ # content_type 'application/json'
100
+ # MultiJson.encode(request.env)
101
+ # end
102
+ #end
103
+ #
104
+ #use Rack::Session::Cookie
105
+ #
106
+ #use OmniAuth::Builder do
107
+ # provider :facebook, ENV['APP_ID'], ENV['APP_SECRET'], :scope => SCOPE
108
+ #end
109
+ #
110
+ #run App.new
@@ -0,0 +1,47 @@
1
+ module Oauthio
2
+ class AccessToken < OAuth2::AccessToken
3
+ attr_reader :provider, :oauth_token, :oauth_token_secret
4
+
5
+ class << self
6
+ # Initializes an AccessToken from a Hash
7
+ #
8
+ # @param [Client] the OAuth2::Client instance
9
+ # @param [Hash] a hash of AccessToken property values
10
+ # @return [AccessToken] the initalized AccessToken
11
+ def from_hash(client, hash)
12
+ # new(client, hash.delete('access_token') || hash.delete(:access_token), hash)
13
+ new(client,
14
+ hash.delete('provider') || hash.delete(:provider),
15
+ hash.delete('access_token') || hash.delete(:access_token),
16
+ hash.delete('oauth_token') || hash.delete(:oauth_token),
17
+ hash.delete('oauth_token_secret') || hash.delete(:oauth_token_secret),
18
+ hash)
19
+ end
20
+ end
21
+
22
+ def initialize(client, provider, token, oauth_token, oauth_token_secret, opts = {})
23
+ super client, token, opts
24
+ @provider = provider
25
+ @oauth_token = oauth_token.to_s
26
+ @oauth_token_secret = oauth_token_secret.to_s
27
+ end
28
+
29
+ def me()
30
+ k = @client.id
31
+ # oauthv = 1 # TODO: Update this
32
+
33
+ if !@token.empty?
34
+ # oauthv=#{oauthv}
35
+ oauthio_header = "k=#{k}&access_token=#{@token}"
36
+ elsif !@oauth_token.empty? && !@oauth_token_secret.empty?
37
+ # oauthv=#{oauthv}
38
+ oauthio_header = "k=#{k}&oauth_token=#{@oauth_token}&oauth_token_secret=#{@oauth_token_secret}"
39
+ else
40
+ # TODO: Throw error if no tokens found
41
+ end
42
+ opts = {headers: {oauthio: oauthio_header}}
43
+ me_url = client.me_url(provider)
44
+ request(:get, me_url, opts)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,158 @@
1
+ module Oauthio
2
+ class Client < ::OAuth2::Client
3
+
4
+ # Instantiate a new OAuth 2.0 client using the
5
+ # Client ID and Client Secret registered to your
6
+ # application.
7
+ #
8
+ # @param [String] client_id the client_id value
9
+ # @param [String] client_secret the client_secret value
10
+ # @param [Hash] opts the options to create the client with
11
+ # @option opts [String] :site the OAuth2 provider site host
12
+ # @option opts [String] :authorize_url ('/oauth/authorize') absolute or relative URL path to the Authorization endpoint
13
+ # @option opts [String] :token_url ('/oauth/token') absolute or relative URL path to the Token endpoint
14
+ # @option opts [Symbol] :token_method (:post) HTTP method to use to request token (:get or :post)
15
+ # @option opts [Hash] :connection_opts ({}) Hash of connection options to pass to initialize Faraday with
16
+ # @option opts [FixNum] :max_redirects (5) maximum number of redirects to follow
17
+ # @option opts [Boolean] :raise_errors (true) whether or not to raise an OAuth2::Error
18
+ # on responses with 400+ status codes
19
+ # @yield [builder] The Faraday connection builder
20
+ def initialize(client_id, client_secret, opts = {}, &block)
21
+ _opts = opts.dup
22
+ @id = client_id
23
+ @secret = client_secret
24
+ @site = _opts.delete(:site)
25
+ @state = _opts.delete(:state)
26
+ ssl = _opts.delete(:ssl)
27
+ @options = {:authorize_url => '/auth',
28
+ :token_url => '/auth/access_token',
29
+ :me_url => '/auth/:provider/me',
30
+ :token_method => :post,
31
+ :connection_opts => {},
32
+ :connection_build => block,
33
+ :max_redirects => 5,
34
+ :raise_errors => true}.merge(_opts)
35
+ @options[:connection_opts][:ssl] = ssl if ssl
36
+ end
37
+
38
+ def me_url(provider, params = nil)
39
+ connection.build_url(options[:me_url], params).to_s.sub(/:provider/, provider)
40
+ end
41
+
42
+ # Makes a request relative to the specified site root.
43
+ #
44
+ # @param [Symbol] verb one of :get, :post, :put, :delete
45
+ # @param [String] url URL path of request
46
+ # @param [Hash] opts the options to make the request with
47
+ # @option opts [Hash] :params additional query parameters for the URL of the request
48
+ # @option opts [Hash, String] :body the body of the request
49
+ # @option opts [Hash] :headers http request headers
50
+ # @option opts [Boolean] :raise_errors whether or not to raise an OAuth2::Error on 400+ status
51
+ # code response for this request. Will default to client option
52
+ # @option opts [Symbol] :parse @see Response::initialize
53
+ # @yield [req] The Faraday request
54
+ def request(verb, url, opts = {}) # rubocop:disable CyclomaticComplexity, MethodLength
55
+ url = connection.build_url(url, opts[:params]).to_s
56
+
57
+ response = connection.run_request(verb, url, opts[:body], opts[:headers]) do |req|
58
+ yield(req) if block_given?
59
+ end
60
+
61
+ # Only really care about the status and the actual return body.
62
+ # Oauth2 strategy wraps the response in a Response object that handles parsing and whatnot. That is great when
63
+ # support for multiple options is needed, however we only have to conform to a single interface. We will take
64
+ # the easy route of always expecting a json response.
65
+ status = response.status
66
+ headers = response.headers
67
+ response = JSON.parse(response.body)
68
+ response['status'] = status
69
+ response['headers'] = headers
70
+ response = Hashie::Mash.new response
71
+
72
+ case response.status
73
+ when 301, 302, 303, 307
74
+ opts[:redirect_count] ||= 0
75
+ opts[:redirect_count] += 1
76
+ return response if opts[:redirect_count] > options[:max_redirects]
77
+ if response.status == 303
78
+ verb = :get
79
+ opts.delete(:body)
80
+ end
81
+ request(verb, response.headers['location'], opts)
82
+ when 200..299, 300..399
83
+ # on non-redirecting 3xx statuses, just return the response
84
+ response
85
+ when 400..599
86
+ error = OAuth2::Error.new(response)
87
+ fail(error) if opts.fetch(:raise_errors, options[:raise_errors])
88
+ response.error = error
89
+ response
90
+ else
91
+ error = OAuth2::Error.new(response)
92
+ fail(error, "Unhandled status code value of #{response.status}")
93
+ end
94
+ end
95
+
96
+ # Initializes an AccessToken by making a request to the token endpoint
97
+ #
98
+ # @param [Hash] params a Hash of params for the token endpoint
99
+ # @param [Hash] access token options, to pass to the AccessToken object
100
+ # @param [Class] class of access token for easier subclassing OAuth2::AccessToken
101
+ # @return [AccessToken] the initalized AccessToken
102
+ def get_token(params, access_token_opts = {}, access_token_class = AccessToken)
103
+ opts = {:raise_errors => options[:raise_errors], :parse => params.delete(:parse)}
104
+ if options[:token_method] == :post
105
+ headers = params.delete(:headers)
106
+ opts[:body] = params
107
+ opts[:headers] = {'Content-Type' => 'application/x-www-form-urlencoded'}
108
+ opts[:headers].merge!(headers) if headers
109
+ else
110
+ opts[:params] = params
111
+ end
112
+ response = request(options[:token_method], token_url, opts)
113
+
114
+ # Verify state in the response matches the one in the session
115
+ if response.state != @state
116
+ raise ::OmniAuth::Strategies::OAuth2::CallbackError.new(nil, :csrf_detected);
117
+ end
118
+
119
+ # error = Error.new(response)
120
+ # fail(error) if options[:raise_errors] && !(response.parsed.is_a?(Hash) && response.parsed['access_token'])
121
+
122
+ provider_client = ::Oauthio::Client.new(@id, @secret, { :site => @site })
123
+ access_token_class.from_hash(provider_client, response.merge(access_token_opts))
124
+ end
125
+
126
+ # The Authorization Code strategy
127
+ #
128
+ # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1
129
+ def auth_code
130
+ @auth_code ||= Oauthio::Strategy::AuthCode.new(self)
131
+ end
132
+
133
+ # The Implicit strategy
134
+ #
135
+ # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-26#section-4.2
136
+ def implicit
137
+ @implicit ||= OAuth2::Strategy::Implicit.new(self)
138
+ end
139
+
140
+ # The Resource Owner Password Credentials strategy
141
+ #
142
+ # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.3
143
+ def password
144
+ @password ||= OAuth2::Strategy::Password.new(self)
145
+ end
146
+
147
+ # The Client Credentials strategy
148
+ #
149
+ # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.4
150
+ def client_credentials
151
+ @client_credentials ||= OAuth2::Strategy::ClientCredentials.new(self)
152
+ end
153
+
154
+ def assertion
155
+ @assertion ||= OAuth2::Strategy::Assertion.new(self)
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,84 @@
1
+ module Oauthio
2
+ module Providers
3
+ class Oauthio
4
+ def initialize(access_token, secret, options)
5
+ @access_token = access_token
6
+ @secret = secret
7
+ @options = options
8
+ end
9
+
10
+ def uid
11
+ # This might not be uniform across all providers. Need to talk to oauthd guys to see if we can get the id
12
+ # in the list of things parsed out of the raw data.
13
+ raw_info['id']
14
+ end
15
+
16
+ def skip_info?
17
+ false
18
+ end
19
+
20
+ def info
21
+ prune!({
22
+ 'name' => _raw_info['name'],
23
+ 'alias' => _raw_info['alias'],
24
+ 'bio' => _raw_info['bio'],
25
+ 'avatar' => _raw_info['avatar'],
26
+ 'firstname' => _raw_info['firstname'],
27
+ 'lastname' => _raw_info['lastname'],
28
+ 'gender' => _raw_info['gender'],
29
+ 'location' => _raw_info['location'],
30
+ 'local' => _raw_info['local'],
31
+ 'company' => _raw_info['company'],
32
+ 'occupation' => _raw_info['occupation'],
33
+ 'language' => _raw_info['language'],
34
+ 'birthdate' => _raw_info['birthdate'],
35
+ })
36
+ end
37
+
38
+ def extra
39
+ hash = {}
40
+ hash['raw_info'] = raw_info unless skip_info?
41
+ prune! hash
42
+ end
43
+
44
+ def _raw_info
45
+ @_raw_info ||= @access_token.me()['data'] || {}
46
+ @_raw_info
47
+ end
48
+
49
+ def raw_info
50
+ @raw_info ||= _raw_info['raw'] || {}
51
+ end
52
+
53
+ def info_options
54
+ # params = {:appsecret_proof => appsecret_proof}
55
+ # params.merge!({:fields => @options[:info_fields]}) if @options[:info_fields]
56
+ # params.merge!({:locale => @options[:locale]}) if @options[:locale]
57
+ #
58
+ # {:params => params}
59
+ end
60
+
61
+ def appsecret_proof
62
+ # @appsecret_proof ||= OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, @secret, @access_token.token)
63
+ end
64
+
65
+ def credentials
66
+ hash = {}
67
+ hash.merge!('token' => @access_token.token) if !@access_token.token.empty?
68
+ hash.merge!('oauth_token' => @access_token.oauth_token,
69
+ 'oauth_token_secret' => @access_token.oauth_token_secret) if !@access_token.oauth_token.empty? && !@access_token.oauth_token_secret.empty?
70
+ hash.merge!('refresh_token' => @access_token.refresh_token) if @access_token.expires? && @access_token.refresh_token
71
+ hash.merge!('expires_at' => @access_token.expires_at) if @access_token.expires?
72
+ hash.merge!('expires' => @access_token.expires?)
73
+ hash
74
+ end
75
+
76
+ def prune!(hash)
77
+ hash.delete_if do |_, v|
78
+ prune!(v) if v.is_a?(Hash)
79
+ v.nil? || (v.respond_to?(:empty?) && v.empty?)
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,36 @@
1
+ module Oauthio
2
+ module Strategy
3
+ class AuthCode < OAuth2::Strategy::AuthCode
4
+ def initialize(client)
5
+ @client = client
6
+ end
7
+
8
+ # The required query parameters for the authorize URL
9
+ #
10
+ # @param [Hash] params additional query parameters
11
+ def authorize_params(params={})
12
+ params.merge('k' => @client.id)
13
+ end
14
+
15
+ #TODO: Put this in base.rb
16
+ # The OAuth client_id and client_secret
17
+ #
18
+ # @return [Hash]
19
+ def client_params
20
+ {'key' => @client.id, 'secret' => @client.secret}
21
+ end
22
+
23
+ # Retrieve an access token given the specified validation code.
24
+ #
25
+ # @param [String] code The Authorization Code value
26
+ # @param [Hash] params additional params
27
+ # @param [Hash] opts options
28
+ # @note that you must also provide a :redirect_uri with most OAuth 2.0 providers
29
+ def get_token(code, params = {}, opts = {})
30
+ params = {'code' => code}.merge(client_params).merge(params)
31
+ @client.get_token(params, opts)
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,5 @@
1
+ module OmniAuth
2
+ module Oauthio
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ require 'omniauth/oauthio/version'
2
+ require 'omniauth/strategies/oauthio'
3
+
4
+ require 'oauthio/access_token'
5
+ require 'oauthio/client'
6
+ require 'oauthio/strategy/auth_code'
7
+ require 'oauthio/providers/oauthio'
8
+
9
+