omniauth-yahoo-oauth2 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +38 -27
- data/lib/omniauth-yahoo-oauth2.rb +1 -1
- data/lib/omniauth/strategies/yahoo_oauth2.rb +137 -33
- data/lib/omniauth/yahoo_oauth2.rb +1 -1
- data/lib/omniauth/yahoo_oauth2/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d5a2c23bd49d42781032387a982ba92dcf388a5946b3a75ab70e33b711959e36
|
4
|
+
data.tar.gz: 20b3e2e88fb855dd62a562b840a5259534da733e3a8728d683f85554db6b2cb9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f00d924baf2b6bda0c11c3d2bbd331d7afab7f82cc3fb953102adabbf5186f4ee3fab3c1f7a0cfcb87cde1a9300eea27a1f5f77b8f3e4ec7860b6ffb35941a6
|
7
|
+
data.tar.gz: e640145bfa89799591d54ec4d78414cbc066e3161c2c1ab662e6ab861ff5f1f3b737a469d2b5b646bd21376b3e06ccf8fa15c7adbbdac05c80a0792514c77f4f
|
data/README.md
CHANGED
@@ -1,56 +1,67 @@
|
|
1
1
|
## omniauth-yahoo-oauth2 ##
|
2
2
|
|
3
|
-
An unofficial, hastily-written Oauth2 OmniAuth strategy for Yahoo. Uses the
|
3
|
+
An unofficial, hastily-written Oauth2 OmniAuth strategy for Yahoo. Uses the
|
4
|
+
authorization flow described at
|
5
|
+
https://developer.yahoo.com/oauth2/guide/flows_authcode/.
|
4
6
|
|
5
7
|
Built using https://github.com/intridea/omniauth-oauth2.
|
6
8
|
|
7
9
|
## Setup ##
|
8
10
|
`gem install omniauth-yahoo-oauth2`
|
9
11
|
|
10
|
-
Create an app at https://developer.yahoo.com/apps to get a Yahoo client ID and
|
12
|
+
Create an app at https://developer.yahoo.com/apps to get a Yahoo client ID and
|
13
|
+
secret.
|
11
14
|
|
12
15
|
## Usage ##
|
13
16
|
```ruby
|
14
17
|
# In an initializer
|
15
18
|
Rails.application.config.middleware.use OmniAuth::Builder do
|
16
|
-
provider :yahoo_oauth2, yahoo_client_id, yahoo_secret,
|
17
|
-
name: 'yahoo'
|
19
|
+
provider :yahoo_oauth2, yahoo_client_id, yahoo_secret, name: 'yahoo'
|
18
20
|
end
|
19
21
|
```
|
20
22
|
|
21
23
|
See https://github.com/intridea/omniauth for Omniauth instructions.
|
22
24
|
|
23
25
|
## Notes ##
|
24
|
-
OmniAuth doesn't currently have built-in support for Basic Authentication for retrieving OAuth tokens, so `YahooOauth2#build_access_token` handles this inline.
|
25
26
|
|
26
|
-
|
27
|
+
OmniAuth doesn't currently have built-in support for Basic Authentication for
|
28
|
+
retrieving OAuth2 tokens, so `YahooOauth2::Client` overrides
|
29
|
+
`OAuth2::Client#get_token`. Yahoo also requires `redirect_uri` to be set when
|
30
|
+
refreshing the `access_token`, so `YahooOauth2::AccessToken` overrides
|
31
|
+
`OAuth2::AccessToken#refresh!` to handle that.
|
32
|
+
|
33
|
+
As with other OAuth2 providers, Yahoo returns an `access_token`, a
|
34
|
+
`refresh_token`, and an expiration time for the `access_token`. They are
|
35
|
+
available in the credentials hash in the callback:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
credentials = request.env.fetch('omniauth.auth').fetch(:credentials)
|
39
|
+
tokens_hash = {
|
40
|
+
access_token: credentials[:token],
|
41
|
+
refresh_token: credentials[:refresh_token],
|
42
|
+
expires_at: credentials[:expires_at]
|
43
|
+
}
|
44
|
+
```
|
45
|
+
|
46
|
+
They should be saved to your application's database. You can use the
|
47
|
+
`access_token` directly or use `YahooOauth2::AccessToken` for requests:
|
27
48
|
|
28
49
|
```ruby
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
50
|
+
client = YahooOauth2::Client.new(YAHOO_CLIENT_ID, YAHOO_SECRET)
|
51
|
+
token = YahooOauth2::AccessToken.from_hash(client, tokens_hash)
|
52
|
+
token.get(
|
53
|
+
"https://social.yahooapis.com/v1/user/#{uid}/profile?format=json"
|
54
|
+
).parsed
|
33
55
|
```
|
34
56
|
|
35
|
-
|
57
|
+
And to refresh the access token once it has expired:
|
36
58
|
|
37
59
|
```ruby
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
authorize_url: '/oauth2/request_auth',
|
44
|
-
token_url: '/oauth2/get_token',
|
45
|
-
})
|
46
|
-
|
47
|
-
auth = "Basic #{Base64.strict_encode64("#{YAHOO_CLIENT_ID}:#{YAHOO_SECRET}")}"
|
48
|
-
|
49
|
-
new_token = oauth_client.get_token({
|
50
|
-
redirect_uri: YOUR_CALLBACK_URL,
|
51
|
-
refresh_token: YOUR_REFRESH_TOKEN,
|
52
|
-
grant_type: 'refresh_token',
|
53
|
-
headers: { 'Authorization' => auth } })
|
60
|
+
old_token = YahooOauth2::AccessToken.from_hash(client, tokens_hash)
|
61
|
+
if old_token.expired?
|
62
|
+
new_token = old_token.refresh!
|
63
|
+
new_token.to_hash # => update your database with this
|
64
|
+
end
|
54
65
|
```
|
55
66
|
|
56
67
|
## TODO ##
|
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require 'omniauth/yahoo_oauth2'
|
@@ -1,49 +1,153 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "jwt"
|
1
4
|
require 'omniauth/strategies/oauth2'
|
2
|
-
require 'base64'
|
3
5
|
|
4
6
|
module OmniAuth
|
5
7
|
module Strategies
|
6
8
|
class YahooOauth2 < OmniAuth::Strategies::OAuth2
|
7
|
-
|
8
|
-
|
9
|
+
|
10
|
+
OPEN_ID_CONNECT_SCOPES = "openid,profile,email"
|
11
|
+
|
12
|
+
ALLOWED_ISSUERS = %w[
|
13
|
+
https://api.login.yahoo.com
|
14
|
+
api.login.yahoo.com
|
15
|
+
login.yahoo.com
|
16
|
+
].freeze
|
17
|
+
|
18
|
+
option :name, 'yahoo'
|
19
|
+
|
20
|
+
option :userinfo_url, "/openid/v1/userinfo"
|
21
|
+
|
9
22
|
option :client_options, {
|
10
|
-
site:
|
11
|
-
authorize_url:
|
12
|
-
token_url:
|
23
|
+
site: "https://api.login.yahoo.com",
|
24
|
+
authorize_url: "/oauth2/request_auth",
|
25
|
+
token_url: "/oauth2/get_token",
|
13
26
|
}
|
14
27
|
|
15
|
-
|
28
|
+
option :skip_jwt, false
|
29
|
+
option :jwt_leeway, 300
|
30
|
+
|
31
|
+
option :authorize_params, {
|
32
|
+
response_type: 'code',
|
33
|
+
}
|
34
|
+
|
35
|
+
option :authorize_options, %i[
|
36
|
+
language
|
37
|
+
login_hint
|
38
|
+
max_age
|
39
|
+
prompt
|
40
|
+
redirect_uri
|
41
|
+
scope
|
42
|
+
state
|
43
|
+
]
|
44
|
+
|
45
|
+
uid { raw_info['sub'] }
|
16
46
|
|
17
47
|
info do
|
18
|
-
{
|
19
|
-
name:
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
48
|
+
prune!({
|
49
|
+
name: raw_info["name"],
|
50
|
+
email: verified_email,
|
51
|
+
unverified_email: raw_info['email'],
|
52
|
+
email_verified: raw_info["email_verified"],
|
53
|
+
first_name: raw_info["given_name"],
|
54
|
+
last_name: raw_info["family_name"],
|
55
|
+
nickname: raw_info["nickname"],
|
56
|
+
gender: raw_info["gender"],
|
57
|
+
locale: raw_info['locale'],
|
58
|
+
image: raw_info['picture'],
|
59
|
+
phone: raw_info["phone_number"],
|
60
|
+
phone_verified: raw_info["phone_number_verified"],
|
24
61
|
urls: {
|
25
|
-
|
26
|
-
|
27
|
-
}
|
28
|
-
}
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
token
|
41
|
-
end
|
42
|
-
|
62
|
+
profile: raw_info['profile'],
|
63
|
+
website: raw_info['website'],
|
64
|
+
},
|
65
|
+
})
|
66
|
+
end
|
67
|
+
|
68
|
+
# n.b. renamed raw_info to userinfo. Userinfo is part of the OIDc standard.
|
69
|
+
extra do
|
70
|
+
hash = {}
|
71
|
+
hash[:userinfo] = raw_info unless skip_info?
|
72
|
+
hash[:id_token] = access_token["id_token"]
|
73
|
+
hash[:id_info] = decode_info_token
|
74
|
+
prune! hash
|
75
|
+
end
|
76
|
+
|
43
77
|
def raw_info
|
44
|
-
|
45
|
-
|
78
|
+
@raw_info ||= access_token.get(userinfo_url).parsed
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
# This follows the example in omniauth-google-oauth2.
|
84
|
+
#
|
85
|
+
# Probably better to set the redirect_uri as a client option when creating
|
86
|
+
# the client, because OAuth2::Client knows how to handle it, but that
|
87
|
+
# requires updating OmniAuth::Strategies::OAuth2.
|
88
|
+
def callback_url
|
89
|
+
options[:redirect_uri] || (full_host + script_name + callback_path)
|
90
|
+
end
|
91
|
+
|
92
|
+
def userinfo_url
|
93
|
+
options.client_options.site + options.userinfo_url
|
94
|
+
end
|
95
|
+
|
96
|
+
# This is copied from the omniauth-google-oauth2 gem
|
97
|
+
def verified_email
|
98
|
+
raw_info['email_verified'] ? raw_info['email'] : nil
|
99
|
+
end
|
100
|
+
|
101
|
+
# This is copied from the omniauth-google-oauth2 gem
|
102
|
+
def prune!(hash)
|
103
|
+
hash.delete_if do |_, v|
|
104
|
+
prune!(v) if v.is_a?(Hash)
|
105
|
+
v.nil? || (v.respond_to?(:empty?) && v.empty?)
|
106
|
+
end
|
46
107
|
end
|
108
|
+
|
109
|
+
# super saves SecureRandom state to session and merges authorize_options
|
110
|
+
#
|
111
|
+
# This follows the example in omniauth-google-oauth2 and
|
112
|
+
# merges any request param with the same name as an authorize_option.
|
113
|
+
# It then saves state to the session (in case it was overwritten).
|
114
|
+
#
|
115
|
+
# Probably the better way to handle this is to build it into "options_for"
|
116
|
+
# and have another option (e.g. authorize_request_params).
|
117
|
+
def authorize_params
|
118
|
+
super.tap do |params|
|
119
|
+
options[:authorize_options].each do |k|
|
120
|
+
unless [nil, ''].include?(request.params[k.to_s])
|
121
|
+
params[k] = request.params[k.to_s]
|
122
|
+
end
|
123
|
+
session['omniauth.state'] = params[:state] if params[:state]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# This is copied from the omniauth-google-oauth2 gem
|
129
|
+
def decode_info_token
|
130
|
+
unless options[:skip_jwt] || access_token['id_token'].nil?
|
131
|
+
decoded = ::JWT.decode(access_token['id_token'], nil, false).first
|
132
|
+
|
133
|
+
# We have to manually verify the claims because the third parameter to
|
134
|
+
# JWT.decode is false since no verification key is provided.
|
135
|
+
::JWT::Verify.verify_claims(decoded,
|
136
|
+
verify_iss: true,
|
137
|
+
iss: ALLOWED_ISSUERS,
|
138
|
+
verify_aud: true,
|
139
|
+
aud: options.client_id,
|
140
|
+
verify_sub: false,
|
141
|
+
verify_expiration: true,
|
142
|
+
verify_not_before: true,
|
143
|
+
verify_iat: true,
|
144
|
+
verify_jti: false,
|
145
|
+
leeway: options[:jwt_leeway])
|
146
|
+
|
147
|
+
decoded
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
47
151
|
end
|
48
152
|
end
|
49
153
|
end
|
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require 'omniauth/strategies/yahoo_oauth2'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omniauth-yahoo-oauth2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Amir Manji
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-05-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: omniauth
|
@@ -86,8 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
86
|
- !ruby/object:Gem::Version
|
87
87
|
version: '0'
|
88
88
|
requirements: []
|
89
|
-
|
90
|
-
rubygems_version: 2.2.2
|
89
|
+
rubygems_version: 3.0.3
|
91
90
|
signing_key:
|
92
91
|
specification_version: 4
|
93
92
|
summary: A Yahoo OAuth2 strategy for OmniAuth.
|