omniauth-oauthio 0.1.0 → 0.2.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 +4 -4
- data/.gitignore +1 -0
- data/README.md +19 -8
- data/example/Gemfile +1 -0
- data/example/Gemfile.lock +38 -24
- data/example/app.rb +152 -0
- data/example/config.ru +8 -107
- data/lib/oauthio/access_token.rb +0 -1
- data/lib/oauthio/client.rb +9 -2
- data/lib/oauthio/strategy/auth_code.rb +7 -0
- data/lib/omniauth/oauthio/version.rb +1 -1
- data/lib/omniauth/strategies/oauthio.rb +54 -66
- data/omniauth-oauthio.gemspec +1 -2
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d37a4503efe522eb66a84b32a32711757aae4d2
|
4
|
+
data.tar.gz: e8befcc5493e673f02ab3284d74c489357206e29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72832698e7031e680ba868d66958034abafd4c202b72ff7d41c55edc5f91540baa65c7089d11bca36be7e363557c42367a786d900955c095b4333a894b416e37
|
7
|
+
data.tar.gz: aa6173e79c1fcf85ea5abb981bd068e3db13ad7a2d6f62ec32ba0e28b732db93463e60e9e85ff40276d28300f75a5d95913555c924ef204cd5eaa48d7fd4ee0f
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -3,14 +3,6 @@ omniauth-oauthio
|
|
3
3
|
|
4
4
|
OAuth.io Strategy for OmniAuth
|
5
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
6
|
## Installing
|
15
7
|
|
16
8
|
Add to your `Gemfile`:
|
@@ -79,6 +71,25 @@ To use with devise, in `config/initializers/devise.rb`
|
|
79
71
|
config.omniauth :oauthio, ENV['OAUTHIO_PUBLIC_KEY'], ENV['OAUTHIO_SECRET_KEY']
|
80
72
|
```
|
81
73
|
|
74
|
+
Add your devise routes in `config/routes.rb`
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
devise_for :users, :skip => [:omniauth_callbacks]
|
78
|
+
devise_scope :user do
|
79
|
+
match "/users/auth/:provider(/:sub_provider)",
|
80
|
+
constraints: { provider: /oauthio/ },
|
81
|
+
to: "users/omniauth_callbacks#passthru",
|
82
|
+
as: :omniauth_authorize,
|
83
|
+
via: [:get, :post]
|
84
|
+
|
85
|
+
match "/users/auth/:action(/:sub_provider)/callback",
|
86
|
+
constraints: { action: /oauthio/, sub_provider: /twitter|google/ },
|
87
|
+
to: "users/omniauth_callbacks",
|
88
|
+
as: :omniauth_callback,
|
89
|
+
via: [:get, :post]
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
82
93
|
### Omniauth
|
83
94
|
|
84
95
|
Add an oauthio callback in `app/controllers/users/omniauth_callbacks_controller.rb`
|
data/example/Gemfile
CHANGED
data/example/Gemfile.lock
CHANGED
@@ -1,44 +1,58 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ../
|
3
3
|
specs:
|
4
|
-
omniauth-
|
5
|
-
omniauth-oauth2 (~> 1.
|
4
|
+
omniauth-oauthio (0.1.1)
|
5
|
+
omniauth-oauth2 (~> 1.2)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
jwt (0.
|
15
|
-
|
16
|
-
|
17
|
-
multipart-post (
|
18
|
-
oauth2 (0.
|
19
|
-
faraday (
|
20
|
-
|
21
|
-
|
22
|
-
|
10
|
+
backports (3.6.0)
|
11
|
+
faraday (0.9.0)
|
12
|
+
multipart-post (>= 1.2, < 3)
|
13
|
+
hashie (3.2.0)
|
14
|
+
jwt (1.0.0)
|
15
|
+
multi_json (1.10.1)
|
16
|
+
multi_xml (0.5.5)
|
17
|
+
multipart-post (2.0.0)
|
18
|
+
oauth2 (1.0.0)
|
19
|
+
faraday (>= 0.8, < 0.10)
|
20
|
+
jwt (~> 1.0)
|
21
|
+
multi_json (~> 1.3)
|
22
|
+
multi_xml (~> 0.5)
|
23
23
|
rack (~> 1.2)
|
24
|
-
omniauth (1.
|
25
|
-
hashie (>= 1.2, <
|
26
|
-
rack
|
27
|
-
omniauth-oauth2 (1.
|
28
|
-
|
29
|
-
|
24
|
+
omniauth (1.2.2)
|
25
|
+
hashie (>= 1.2, < 4)
|
26
|
+
rack (~> 1.0)
|
27
|
+
omniauth-oauth2 (1.2.0)
|
28
|
+
faraday (>= 0.8, < 0.10)
|
29
|
+
multi_json (~> 1.3)
|
30
|
+
oauth2 (~> 1.0)
|
31
|
+
omniauth (~> 1.2)
|
30
32
|
rack (1.5.2)
|
31
|
-
rack-protection (1.5.
|
33
|
+
rack-protection (1.5.3)
|
32
34
|
rack
|
33
|
-
|
35
|
+
rack-test (0.6.2)
|
36
|
+
rack (>= 1.0)
|
37
|
+
sinatra (1.4.5)
|
34
38
|
rack (~> 1.4)
|
35
39
|
rack-protection (~> 1.4)
|
36
40
|
tilt (~> 1.3, >= 1.3.4)
|
41
|
+
sinatra-contrib (1.4.2)
|
42
|
+
backports (>= 2.0)
|
43
|
+
multi_json
|
44
|
+
rack-protection
|
45
|
+
rack-test
|
46
|
+
sinatra (~> 1.4.0)
|
47
|
+
tilt (~> 1.3)
|
48
|
+
sinatra-reloader (1.0)
|
49
|
+
sinatra-contrib
|
37
50
|
tilt (1.4.1)
|
38
51
|
|
39
52
|
PLATFORMS
|
40
53
|
ruby
|
41
54
|
|
42
55
|
DEPENDENCIES
|
43
|
-
omniauth-
|
56
|
+
omniauth-oauthio!
|
44
57
|
sinatra
|
58
|
+
sinatra-reloader
|
data/example/app.rb
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require "sinatra/reloader"
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
# configure sinatra
|
6
|
+
set :run, false
|
7
|
+
set :raise_errors, true
|
8
|
+
|
9
|
+
# setup logging to file
|
10
|
+
log = File.new("app.log", "a+")
|
11
|
+
$stdout.reopen(log)
|
12
|
+
$stderr.reopen(log)
|
13
|
+
$stderr.sync = true
|
14
|
+
$stdout.sync = true
|
15
|
+
|
16
|
+
# server-side flow
|
17
|
+
get '/server-side/:provider' do
|
18
|
+
# NOTE: You would just hit this endpoint directly from the browser in a real app. The redirect is just here to
|
19
|
+
# explicit declare this server-side flow.
|
20
|
+
redirect "/auth/oauthio/#{params[:provider]}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# client-side flow
|
24
|
+
get '/client-side' do
|
25
|
+
content_type 'text/html'
|
26
|
+
<<-END
|
27
|
+
<html>
|
28
|
+
<head>
|
29
|
+
<title>Client-side Flow Example</title>
|
30
|
+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js" type="text/javascript"></script>
|
31
|
+
<script src="https://rawgit.com/oauth-io/oauth-js/master/dist/oauth.min.js" type="text/javascript"></script>
|
32
|
+
</head>
|
33
|
+
<body>
|
34
|
+
<div id="oauthio-root"></div>
|
35
|
+
|
36
|
+
<script type="text/javascript">
|
37
|
+
var qs = (function(a) {
|
38
|
+
if (a == "") return {};
|
39
|
+
var b = {};
|
40
|
+
for (var i = 0; i < a.length; ++i)
|
41
|
+
{
|
42
|
+
var p=a[i].split('=');
|
43
|
+
if (p.length != 2) continue;
|
44
|
+
b[p[0]] = decodeURIComponent(p[1].replace(/\\+/g, " "));
|
45
|
+
}
|
46
|
+
return b;
|
47
|
+
})(window.location.search.substr(1).split('&'));
|
48
|
+
|
49
|
+
OAuth.initialize('#{ENV['OAUTHIO_PUBLIC_KEY']}');
|
50
|
+
|
51
|
+
window.onload = function(){
|
52
|
+
if (qs['provider'] != undefined) {
|
53
|
+
var promise = OAuth.callback(qs['provider']);
|
54
|
+
|
55
|
+
promise.done(function (result) {
|
56
|
+
result.me().done(function(me){
|
57
|
+
$('#me').html(JSON.stringify(me));
|
58
|
+
$.post("/auth/oauthio/" + qs['provider'] + "/callback.json", {'state': qs['state'], 'code': result.code})
|
59
|
+
.done(function(r){
|
60
|
+
$('#results').html(JSON.stringify(r));
|
61
|
+
});
|
62
|
+
});
|
63
|
+
});
|
64
|
+
|
65
|
+
promise.fail(function (error) {
|
66
|
+
// handle errors
|
67
|
+
console.log(error);
|
68
|
+
});
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
$(function() {
|
73
|
+
$('p#connect a').click(function(e) {
|
74
|
+
e.preventDefault();
|
75
|
+
var selectedProvider = $('#provider').val();
|
76
|
+
var type = $('#type').val();
|
77
|
+
|
78
|
+
$.get("/auth/oauthio/" + selectedProvider + ".json").done(function(data){
|
79
|
+
var state = data.state
|
80
|
+
if (type == 'popup') {
|
81
|
+
OAuth.popup(selectedProvider, {'state': state})
|
82
|
+
.done(function(result) {
|
83
|
+
//use result.access_token in your API request
|
84
|
+
//or use result.get|post|put|del|patch|me methods (see below)
|
85
|
+
result.me().done(function(me){
|
86
|
+
$('#me').html(JSON.stringify(me));
|
87
|
+
$.post("/auth/oauthio/" + selectedProvider + "/callback.json", {'state': state, 'code': result.code})
|
88
|
+
.done(function(r){
|
89
|
+
$('#results').html(JSON.stringify(r));
|
90
|
+
});
|
91
|
+
});
|
92
|
+
})
|
93
|
+
.fail(function (err) {
|
94
|
+
//handle error with err
|
95
|
+
console.log(err);
|
96
|
+
$('#results').html(err.message)
|
97
|
+
});
|
98
|
+
} else if (type == 'redirect') {
|
99
|
+
OAuth.redirect(selectedProvider, {'state': state}, '/client-side?provider=' + selectedProvider + '&state=' + state);
|
100
|
+
}
|
101
|
+
});
|
102
|
+
});
|
103
|
+
|
104
|
+
$('p#no-sdk-connect a').click(function(e) {
|
105
|
+
e.preventDefault();
|
106
|
+
var selectedProvider = $('#provider').val();
|
107
|
+
document.location = document.location.origin + "/auth/oauthio/" + selectedProvider
|
108
|
+
});
|
109
|
+
|
110
|
+
});
|
111
|
+
</script>
|
112
|
+
|
113
|
+
<select id="provider">
|
114
|
+
<option value="facebook">Facebook</option>
|
115
|
+
<option value="twitter" selected>Twitter</option>
|
116
|
+
<option value="google">Google</option>
|
117
|
+
</select>
|
118
|
+
|
119
|
+
<select id="type">
|
120
|
+
<option value="popup" selected>Popup</option>
|
121
|
+
<option value="redirect">Redirect</option>
|
122
|
+
</select>
|
123
|
+
|
124
|
+
<p id="connect">
|
125
|
+
<a href="#">Connect!</a>
|
126
|
+
</p>
|
127
|
+
|
128
|
+
<p id="no-sdk-connect">
|
129
|
+
<a href="/auth/oauthio/twitter">Redirect w/o JS SDK!</a>
|
130
|
+
</p>
|
131
|
+
|
132
|
+
<p id="me" />
|
133
|
+
<p id="results" />
|
134
|
+
</body>
|
135
|
+
</html>
|
136
|
+
END
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.get_or_post(url,&block)
|
140
|
+
get(url,&block)
|
141
|
+
post(url,&block)
|
142
|
+
end
|
143
|
+
|
144
|
+
get_or_post '/auth/:provider/:sub_provider/callback.?:format?' do
|
145
|
+
content_type 'application/json'
|
146
|
+
MultiJson.encode(request.env)
|
147
|
+
end
|
148
|
+
|
149
|
+
get '/auth/failure' do
|
150
|
+
content_type 'application/json'
|
151
|
+
MultiJson.encode(request.env)
|
152
|
+
end
|
data/example/config.ru
CHANGED
@@ -1,110 +1,11 @@
|
|
1
1
|
require 'bundler/setup'
|
2
|
-
require 'sinatra/base'
|
3
2
|
require 'omniauth-oauthio'
|
3
|
+
require './app.rb'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
5
|
+
use Rack::Session::Cookie, :secret => 'abc123'
|
6
|
+
|
7
|
+
use OmniAuth::Builder do
|
8
|
+
provider :oauthio, ENV['OAUTHIO_PUBLIC_KEY'], ENV['OAUTHIO_PRIVATE_KEY']
|
9
|
+
end
|
10
|
+
|
11
|
+
run Sinatra::Application
|
data/lib/oauthio/access_token.rb
CHANGED
@@ -9,7 +9,6 @@ module Oauthio
|
|
9
9
|
# @param [Hash] a hash of AccessToken property values
|
10
10
|
# @return [AccessToken] the initalized AccessToken
|
11
11
|
def from_hash(client, hash)
|
12
|
-
# new(client, hash.delete('access_token') || hash.delete(:access_token), hash)
|
13
12
|
new(client,
|
14
13
|
hash.delete('provider') || hash.delete(:provider),
|
15
14
|
hash.delete('access_token') || hash.delete(:access_token),
|
data/lib/oauthio/client.rb
CHANGED
@@ -24,7 +24,7 @@ module Oauthio
|
|
24
24
|
@site = _opts.delete(:site)
|
25
25
|
@state = _opts.delete(:state)
|
26
26
|
ssl = _opts.delete(:ssl)
|
27
|
-
@options = {:authorize_url => '/auth',
|
27
|
+
@options = {:authorize_url => '/auth/:provider',
|
28
28
|
:token_url => '/auth/access_token',
|
29
29
|
:me_url => '/auth/:provider/me',
|
30
30
|
:token_method => :post,
|
@@ -36,7 +36,14 @@ module Oauthio
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def me_url(provider, params = nil)
|
39
|
-
connection.build_url(options[:me_url]
|
39
|
+
connection.build_url(options[:me_url].sub(/:provider/, provider), params).to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
# The authorize endpoint URL of the OAuth2 provider
|
43
|
+
#
|
44
|
+
# @param [Hash] params additional query parameters
|
45
|
+
def authorize_url(provider, params = nil)
|
46
|
+
connection.build_url(options[:authorize_url].sub(/:provider/, provider), params).to_s
|
40
47
|
end
|
41
48
|
|
42
49
|
# Makes a request relative to the specified site root.
|
@@ -5,6 +5,13 @@ module Oauthio
|
|
5
5
|
@client = client
|
6
6
|
end
|
7
7
|
|
8
|
+
# The authorization URL endpoint of the provider
|
9
|
+
#
|
10
|
+
# @param [Hash] params additional query parameters for the URL
|
11
|
+
def authorize_url(provider, params = {})
|
12
|
+
@client.authorize_url(provider, authorize_params.merge(params))
|
13
|
+
end
|
14
|
+
|
8
15
|
# The required query parameters for the authorize URL
|
9
16
|
#
|
10
17
|
# @param [Hash] params additional query parameters
|
@@ -3,6 +3,7 @@ require 'base64'
|
|
3
3
|
require 'openssl'
|
4
4
|
require 'rack/utils'
|
5
5
|
require 'uri'
|
6
|
+
require 'json'
|
6
7
|
|
7
8
|
module OmniAuth
|
8
9
|
module Strategies
|
@@ -23,48 +24,16 @@ module OmniAuth
|
|
23
24
|
option :client_id, nil
|
24
25
|
option :client_secret, nil
|
25
26
|
|
26
|
-
# Returns true if the environment recognizes either the
|
27
|
-
# request or callback path.
|
28
|
-
def on_auth_path?
|
29
|
-
on_request_path? || on_callback_path?
|
30
|
-
end
|
31
|
-
|
32
|
-
def client_with_provider(provider)
|
33
|
-
options.client_options.merge!({authorize_url: "#{options.client_options.authorization_url}/#{provider}"})
|
34
|
-
client
|
35
|
-
end
|
36
|
-
|
37
27
|
def current_path
|
38
28
|
# This might not be completely safe. I want to ensure that the current_path does not have a format at the end
|
39
29
|
# so the .json should be removed.
|
40
|
-
super.
|
41
|
-
end
|
42
|
-
|
43
|
-
def on_request_path?
|
44
|
-
if options.request_path.respond_to?(:call)
|
45
|
-
options.request_path.call(env)
|
46
|
-
else
|
47
|
-
on_path?(request_path)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def on_path?(path)
|
52
|
-
current_path.casecmp(path) == 0
|
53
|
-
end
|
54
|
-
|
55
|
-
def on_callback_path?
|
56
|
-
on_path?(callback_path)
|
30
|
+
super.sub(/(\.json)$/, '');
|
57
31
|
end
|
58
32
|
|
59
33
|
def sub_provider
|
60
|
-
|
61
|
-
slashes =
|
62
|
-
|
63
|
-
# return ''
|
64
|
-
return slashes.first.split('.').first
|
65
|
-
end
|
66
|
-
|
67
|
-
test.split('.').first
|
34
|
+
after_base = request.path.split("#{path_prefix}/#{name}/").last
|
35
|
+
slashes = after_base.split('/')
|
36
|
+
slashes.length > 1 ? slashes.first.split('.').first : after_base.split('.').first
|
68
37
|
end
|
69
38
|
|
70
39
|
def request_path
|
@@ -79,24 +48,34 @@ module OmniAuth
|
|
79
48
|
path
|
80
49
|
end
|
81
50
|
|
82
|
-
def path_prefix
|
83
|
-
options[:path_prefix] || OmniAuth.config.path_prefix
|
84
|
-
end
|
85
|
-
|
86
51
|
def request_phase
|
87
52
|
params = authorize_params
|
53
|
+
provider = sub_provider
|
54
|
+
|
55
|
+
opts = {
|
56
|
+
state: params.state
|
57
|
+
}.to_json
|
58
|
+
|
88
59
|
# We may want to skip redirecting the user if calling from a SPA that does not want to reload the page.
|
89
|
-
|
90
|
-
|
91
|
-
json = {state: session['omniauth.state']}.to_json
|
92
|
-
return Rack::Response.new(json, 200, 'content-type' => 'application/json').finish
|
60
|
+
if request.path_info =~ /\.json$/
|
61
|
+
return Rack::Response.new(opts, 200, 'content-type' => 'application/json').finish
|
93
62
|
end
|
94
63
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
64
|
+
redirect client.auth_code.authorize_url(provider, {:redirect_uri => callback_url_with_state(params.state)}.merge({opts: opts}))
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
# note: the callback phase should be the same regardless!
|
69
|
+
#
|
70
|
+
# The request phase though needs to have multiple options
|
71
|
+
# 1. take care of everything the js-sdk does.
|
72
|
+
# 2. partial control where we can get the state to pass to the js-sdk.
|
73
|
+
|
74
|
+
def callback_url_with_state(state)
|
75
|
+
uri = URI.parse(callback_url)
|
76
|
+
new_query_ar = URI.decode_www_form(uri.query || '') << ['state', state]
|
77
|
+
uri.query = URI.encode_www_form(new_query_ar)
|
78
|
+
uri.to_s
|
100
79
|
end
|
101
80
|
|
102
81
|
def auth_hash
|
@@ -110,22 +89,35 @@ module OmniAuth
|
|
110
89
|
end
|
111
90
|
|
112
91
|
def callback_phase
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
92
|
+
if !request.params['code']
|
93
|
+
# TODO: Is there an option we can pass to OAuth.io to prevent it from putting the code in the hash part of the url?
|
94
|
+
# Currently we to parse the hash to get the code and then do an additional redirect.
|
95
|
+
html = '<!DOCTYPE html>
|
96
|
+
<html><head><script>(function() {
|
97
|
+
"use strict";
|
98
|
+
var hash = document.location.hash;
|
99
|
+
var data = JSON.parse(decodeURIComponent(hash.split("=")[1]));
|
100
|
+
var code = data.data.code
|
101
|
+
document.location.href = document.location.origin + document.location.pathname + document.location.search + "&code=" + code
|
102
|
+
//document.location.href = document.location.href + "&code=" + code
|
103
|
+
})();</script></head><body></body></html>'
|
104
|
+
return Rack::Response.new(html, 200).finish
|
118
105
|
end
|
119
106
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
107
|
+
error = request.params['error_reason'] || request.params['error']
|
108
|
+
if error
|
109
|
+
fail!(error, CallbackError.new(request.params['error'], request.params['error_description'] || request.params['error_reason'], request.params['error_uri']))
|
110
|
+
elsif !options.provider_ignores_state && !verified_state?
|
111
|
+
fail!(:csrf_detected, CallbackError.new(:csrf_detected, 'CSRF detected'))
|
112
|
+
else
|
113
|
+
self.access_token = build_access_token
|
114
|
+
self.access_token = access_token.refresh! if access_token.expired?
|
127
115
|
|
128
|
-
|
116
|
+
env['omniauth.auth'] = auth_hash
|
117
|
+
# Delete the omniauth.state after we have verified all requests
|
118
|
+
session.delete('omniauth.state')
|
119
|
+
call_app!
|
120
|
+
end
|
129
121
|
rescue CallbackError => e
|
130
122
|
fail!(:invalid_credentials, e)
|
131
123
|
rescue ::MultiJson::DecodeError => e
|
@@ -137,7 +129,6 @@ module OmniAuth
|
|
137
129
|
end
|
138
130
|
|
139
131
|
protected
|
140
|
-
# Client should only be access via client_with_provider
|
141
132
|
def client
|
142
133
|
state = session['omniauth.state']
|
143
134
|
options.client_options[:state] = state
|
@@ -153,6 +144,3 @@ module OmniAuth
|
|
153
144
|
end
|
154
145
|
end
|
155
146
|
|
156
|
-
|
157
|
-
|
158
|
-
|
data/omniauth-oauthio.gemspec
CHANGED
@@ -13,10 +13,9 @@ Gem::Specification.new do |s|
|
|
13
13
|
|
14
14
|
s.files = `git ls-files`.split("\n")
|
15
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
17
16
|
s.require_paths = ['lib']
|
18
17
|
|
19
|
-
s.add_runtime_dependency 'omniauth-oauth2', '~> 1.
|
18
|
+
s.add_runtime_dependency 'omniauth-oauth2', '~> 1.2'
|
20
19
|
|
21
20
|
s.add_development_dependency 'minitest'
|
22
21
|
s.add_development_dependency 'mocha'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omniauth-oauthio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Rowlands
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: omniauth-oauth2
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +80,7 @@ files:
|
|
80
80
|
- Rakefile
|
81
81
|
- example/Gemfile
|
82
82
|
- example/Gemfile.lock
|
83
|
+
- example/app.rb
|
83
84
|
- example/config.ru
|
84
85
|
- lib/oauthio/access_token.rb
|
85
86
|
- lib/oauthio/client.rb
|