omniauth-yahoo-oauth2 1.1.0 → 1.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 +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.
|