omniauth-oauthio 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+