oauth2 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/oauth2.rb +1 -0
- data/lib/oauth2/access_token.rb +2 -4
- data/lib/oauth2/authenticator.rb +58 -0
- data/lib/oauth2/client.rb +44 -10
- data/lib/oauth2/error.rb +1 -1
- data/lib/oauth2/response.rb +1 -1
- data/lib/oauth2/strategy/assertion.rb +1 -1
- data/lib/oauth2/strategy/auth_code.rb +2 -1
- data/lib/oauth2/strategy/base.rb +0 -7
- data/lib/oauth2/strategy/client_credentials.rb +1 -13
- data/lib/oauth2/strategy/password.rb +1 -1
- data/lib/oauth2/version.rb +1 -1
- data/oauth2.gemspec +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0de0695b29bf1d20066a08a8536d70a9bea3e827
|
4
|
+
data.tar.gz: 184943366118bf412220fbde4ac0d1becdfa2055
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fe7c101b47debe6489b4bad62211d774079f599749fcc7e36fddd076f305db8ae3baab500877656a5a698b1484da1467d3a9b60fff07b9520d9cc314e542f8b
|
7
|
+
data.tar.gz: da02d83327a1c147bd6cf28cc416bcb4c82168c723f17871fcc1a3b16cb42e35726672055a2829234d6e8b565e1d576fc339b747467f38f728e9559cb087b3cc
|
data/lib/oauth2.rb
CHANGED
data/lib/oauth2/access_token.rb
CHANGED
@@ -81,8 +81,6 @@ module OAuth2
|
|
81
81
|
# @note options should be carried over to the new AccessToken
|
82
82
|
def refresh!(params = {})
|
83
83
|
raise('A refresh_token is not available') unless refresh_token
|
84
|
-
params[:client_id] = @client.id
|
85
|
-
params[:client_secret] = @client.secret
|
86
84
|
params[:grant_type] = 'refresh_token'
|
87
85
|
params[:refresh_token] = refresh_token
|
88
86
|
new_token = @client.get_token(params)
|
@@ -105,7 +103,7 @@ module OAuth2
|
|
105
103
|
# @param [Hash] opts the options to make the request with
|
106
104
|
# @see Client#request
|
107
105
|
def request(verb, path, opts = {}, &block)
|
108
|
-
|
106
|
+
configure_authentication!(opts)
|
109
107
|
@client.request(verb, path, opts, &block)
|
110
108
|
end
|
111
109
|
|
@@ -151,7 +149,7 @@ module OAuth2
|
|
151
149
|
|
152
150
|
private
|
153
151
|
|
154
|
-
def
|
152
|
+
def configure_authentication!(opts) # rubocop:disable MethodLength, Metrics/AbcSize
|
155
153
|
case options[:mode]
|
156
154
|
when :header
|
157
155
|
opts[:headers] ||= {}
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module OAuth2
|
4
|
+
class Authenticator
|
5
|
+
attr_reader :mode, :id, :secret
|
6
|
+
|
7
|
+
def initialize(id, secret, mode)
|
8
|
+
@id = id
|
9
|
+
@secret = secret
|
10
|
+
@mode = mode
|
11
|
+
end
|
12
|
+
|
13
|
+
# Apply the request credentials used to authenticate to the Authorization Server
|
14
|
+
#
|
15
|
+
# Depending on configuration, this might be as request params or as an
|
16
|
+
# Authorization header.
|
17
|
+
#
|
18
|
+
# User-provided params and header take precedence.
|
19
|
+
#
|
20
|
+
# @param [Hash] params a Hash of params for the token endpoint
|
21
|
+
# @return [Hash] params amended with appropriate authentication details
|
22
|
+
def apply(params)
|
23
|
+
case mode.to_sym
|
24
|
+
when :basic_auth
|
25
|
+
apply_basic_auth(params)
|
26
|
+
when :request_body
|
27
|
+
apply_params_auth(params)
|
28
|
+
else
|
29
|
+
raise NotImplementedError
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.encode_basic_auth(user, password)
|
34
|
+
'Basic ' + Base64.encode64(user + ':' + password).delete("\n")
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# Adds client_id and client_secret request parameters if they are not
|
40
|
+
# already set.
|
41
|
+
def apply_params_auth(params)
|
42
|
+
{'client_id' => id, 'client_secret' => secret}.merge(params)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Adds an `Authorization` header with Basic Auth credentials if and only if
|
46
|
+
# it is not already set in the params.
|
47
|
+
def apply_basic_auth(params)
|
48
|
+
headers = params.fetch(:headers, {})
|
49
|
+
headers = basic_auth_header.merge(headers)
|
50
|
+
params.merge(:headers => headers)
|
51
|
+
end
|
52
|
+
|
53
|
+
# @see https://tools.ietf.org/html/rfc2617#section-2
|
54
|
+
def basic_auth_header
|
55
|
+
{'Authorization' => self.class.encode_basic_auth(id, secret)}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/oauth2/client.rb
CHANGED
@@ -3,7 +3,7 @@ require 'logger'
|
|
3
3
|
|
4
4
|
module OAuth2
|
5
5
|
# The OAuth2::Client class
|
6
|
-
class Client
|
6
|
+
class Client # rubocop:disable Metrics/ClassLength
|
7
7
|
attr_reader :id, :secret, :site
|
8
8
|
attr_accessor :options
|
9
9
|
attr_writer :connection
|
@@ -16,9 +16,11 @@ module OAuth2
|
|
16
16
|
# @param [String] client_secret the client_secret value
|
17
17
|
# @param [Hash] opts the options to create the client with
|
18
18
|
# @option opts [String] :site the OAuth2 provider site host
|
19
|
+
# @option opts [String] :redirect_uri the absolute URI to the Redirection Endpoint for use in authorization grants and token exchange
|
19
20
|
# @option opts [String] :authorize_url ('/oauth/authorize') absolute or relative URL path to the Authorization endpoint
|
20
21
|
# @option opts [String] :token_url ('/oauth/token') absolute or relative URL path to the Token endpoint
|
21
22
|
# @option opts [Symbol] :token_method (:post) HTTP method to use to request token (:get or :post)
|
23
|
+
# @option opts [Symbol] :auth_scheme (:basic_auth) HTTP method to use to authorize request (:basic_auth or :request_body)
|
22
24
|
# @option opts [Hash] :connection_opts ({}) Hash of connection options to pass to initialize Faraday with
|
23
25
|
# @option opts [FixNum] :max_redirects (5) maximum number of redirects to follow
|
24
26
|
# @option opts [Boolean] :raise_errors (true) whether or not to raise an OAuth2::Error
|
@@ -33,6 +35,7 @@ module OAuth2
|
|
33
35
|
@options = {:authorize_url => '/oauth/authorize',
|
34
36
|
:token_url => '/oauth/token',
|
35
37
|
:token_method => :post,
|
38
|
+
:auth_scheme => :request_body,
|
36
39
|
:connection_opts => {},
|
37
40
|
:connection_build => block,
|
38
41
|
:max_redirects => 5,
|
@@ -52,9 +55,11 @@ module OAuth2
|
|
52
55
|
def connection
|
53
56
|
@connection ||= begin
|
54
57
|
conn = Faraday.new(site, options[:connection_opts])
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
+
if options[:connection_build]
|
59
|
+
conn.build do |b|
|
60
|
+
options[:connection_build].call(b)
|
61
|
+
end
|
62
|
+
end
|
58
63
|
conn
|
59
64
|
end
|
60
65
|
end
|
@@ -62,7 +67,8 @@ module OAuth2
|
|
62
67
|
# The authorize endpoint URL of the OAuth2 provider
|
63
68
|
#
|
64
69
|
# @param [Hash] params additional query parameters
|
65
|
-
def authorize_url(params =
|
70
|
+
def authorize_url(params = {})
|
71
|
+
params = (params || {}).merge(redirection_params)
|
66
72
|
connection.build_url(options[:authorize_url], params).to_s
|
67
73
|
end
|
68
74
|
|
@@ -125,19 +131,23 @@ module OAuth2
|
|
125
131
|
# @param [Hash] access token options, to pass to the AccessToken object
|
126
132
|
# @param [Class] class of access token for easier subclassing OAuth2::AccessToken
|
127
133
|
# @return [AccessToken] the initalized AccessToken
|
128
|
-
def get_token(params, access_token_opts = {}, access_token_class = AccessToken) # rubocop:disable Metrics/AbcSize
|
134
|
+
def get_token(params, access_token_opts = {}, access_token_class = AccessToken) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
135
|
+
params = Authenticator.new(id, secret, options[:auth_scheme]).apply(params)
|
129
136
|
opts = {:raise_errors => options[:raise_errors], :parse => params.delete(:parse)}
|
137
|
+
headers = params.delete(:headers) || {}
|
130
138
|
if options[:token_method] == :post
|
131
|
-
headers = params.delete(:headers)
|
132
139
|
opts[:body] = params
|
133
140
|
opts[:headers] = {'Content-Type' => 'application/x-www-form-urlencoded'}
|
134
|
-
opts[:headers].merge!(headers) if headers
|
135
141
|
else
|
136
142
|
opts[:params] = params
|
143
|
+
opts[:headers] = {}
|
137
144
|
end
|
145
|
+
opts[:headers].merge!(headers)
|
138
146
|
response = request(options[:token_method], token_url, opts)
|
139
|
-
|
140
|
-
|
147
|
+
if options[:raise_errors] && !(response.parsed.is_a?(Hash) && response.parsed['access_token'])
|
148
|
+
error = Error.new(response)
|
149
|
+
raise(error)
|
150
|
+
end
|
141
151
|
access_token_class.from_hash(self, response.parsed.merge(access_token_opts))
|
142
152
|
end
|
143
153
|
|
@@ -172,5 +182,29 @@ module OAuth2
|
|
172
182
|
def assertion
|
173
183
|
@assertion ||= OAuth2::Strategy::Assertion.new(self)
|
174
184
|
end
|
185
|
+
|
186
|
+
# The redirect_uri parameters, if configured
|
187
|
+
#
|
188
|
+
# The redirect_uri query parameter is OPTIONAL (though encouraged) when
|
189
|
+
# requesting authorization. If it is provided at authorization time it MUST
|
190
|
+
# also be provided with the token exchange request.
|
191
|
+
#
|
192
|
+
# Providing the :redirect_uri to the OAuth2::Client instantiation will take
|
193
|
+
# care of managing this.
|
194
|
+
#
|
195
|
+
# @api semipublic
|
196
|
+
#
|
197
|
+
# @see https://tools.ietf.org/html/rfc6749#section-4.1
|
198
|
+
# @see https://tools.ietf.org/html/rfc6749#section-4.1.3
|
199
|
+
# @see https://tools.ietf.org/html/rfc6749#section-4.2.1
|
200
|
+
# @see https://tools.ietf.org/html/rfc6749#section-10.6
|
201
|
+
# @return [Hash] the params to add to a request or URL
|
202
|
+
def redirection_params
|
203
|
+
if options[:redirect_uri]
|
204
|
+
{'redirect_uri' => options[:redirect_uri]}
|
205
|
+
else
|
206
|
+
{}
|
207
|
+
end
|
208
|
+
end
|
175
209
|
end
|
176
210
|
end
|
data/lib/oauth2/error.rb
CHANGED
@@ -27,7 +27,7 @@ module OAuth2
|
|
27
27
|
|
28
28
|
error_message = if opts[:error_description] && opts[:error_description].respond_to?(:encoding)
|
29
29
|
script_encoding = opts[:error_description].encoding
|
30
|
-
response_body.encode(script_encoding)
|
30
|
+
response_body.encode(script_encoding, :invalid => :replace, :undef => :replace)
|
31
31
|
else
|
32
32
|
response_body
|
33
33
|
end
|
data/lib/oauth2/response.rb
CHANGED
@@ -27,7 +27,7 @@ module OAuth2
|
|
27
27
|
# Adds a new content type parser.
|
28
28
|
#
|
29
29
|
# @param [Symbol] key A descriptive symbol key such as :json or :query.
|
30
|
-
# @param [Array] One or more mime types to which this parser applies.
|
30
|
+
# @param [Array] mime_types One or more mime types to which this parser applies.
|
31
31
|
# @yield [String] A block returning parsed content.
|
32
32
|
def self.register_parser(key, mime_types, &block)
|
33
33
|
key = key.to_sym
|
@@ -25,7 +25,8 @@ module OAuth2
|
|
25
25
|
# @param [Hash] opts options
|
26
26
|
# @note that you must also provide a :redirect_uri with most OAuth 2.0 providers
|
27
27
|
def get_token(code, params = {}, opts = {})
|
28
|
-
params = {'grant_type' => 'authorization_code', 'code' => code}.merge(
|
28
|
+
params = {'grant_type' => 'authorization_code', 'code' => code}.merge(@client.redirection_params).merge(params)
|
29
|
+
|
29
30
|
@client.get_token(params, opts)
|
30
31
|
end
|
31
32
|
end
|
data/lib/oauth2/strategy/base.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'base64'
|
2
|
-
|
3
1
|
module OAuth2
|
4
2
|
module Strategy
|
5
3
|
# The Client Credentials Strategy
|
@@ -18,19 +16,9 @@ module OAuth2
|
|
18
16
|
# @param [Hash] params additional params
|
19
17
|
# @param [Hash] opts options
|
20
18
|
def get_token(params = {}, opts = {})
|
21
|
-
|
22
|
-
params['grant_type'] = 'client_credentials'
|
23
|
-
params.merge!(request_body ? client_params : {:headers => {'Authorization' => authorization(client_params['client_id'], client_params['client_secret'])}})
|
19
|
+
params = params.merge('grant_type' => 'client_credentials')
|
24
20
|
@client.get_token(params, opts.merge('refresh_token' => nil))
|
25
21
|
end
|
26
|
-
|
27
|
-
# Returns the Authorization header value for Basic Authentication
|
28
|
-
#
|
29
|
-
# @param [String] The client ID
|
30
|
-
# @param [String] the client secret
|
31
|
-
def authorization(client_id, client_secret)
|
32
|
-
'Basic ' + Base64.encode64(client_id + ':' + client_secret).delete("\n")
|
33
|
-
end
|
34
22
|
end
|
35
23
|
end
|
36
24
|
end
|
@@ -19,7 +19,7 @@ module OAuth2
|
|
19
19
|
def get_token(username, password, params = {}, opts = {})
|
20
20
|
params = {'grant_type' => 'password',
|
21
21
|
'username' => username,
|
22
|
-
'password' => password}.merge(
|
22
|
+
'password' => password}.merge(params)
|
23
23
|
@client.get_token(params, opts)
|
24
24
|
end
|
25
25
|
end
|
data/lib/oauth2/version.rb
CHANGED
data/oauth2.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'oauth2/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.add_dependency 'faraday', ['>= 0.8', '< 0.
|
7
|
+
spec.add_dependency 'faraday', ['>= 0.8', '< 0.11']
|
8
8
|
spec.add_dependency 'jwt', '~> 1.0'
|
9
9
|
spec.add_dependency 'multi_json', '~> 1.3'
|
10
10
|
spec.add_dependency 'multi_xml', '~> 0.5'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oauth2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Bleigh
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-12-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faraday
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
version: '0.8'
|
21
21
|
- - "<"
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: '0.
|
23
|
+
version: '0.11'
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
version: '0.8'
|
31
31
|
- - "<"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0.
|
33
|
+
version: '0.11'
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: jwt
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +122,7 @@ files:
|
|
122
122
|
- README.md
|
123
123
|
- lib/oauth2.rb
|
124
124
|
- lib/oauth2/access_token.rb
|
125
|
+
- lib/oauth2/authenticator.rb
|
125
126
|
- lib/oauth2/client.rb
|
126
127
|
- lib/oauth2/error.rb
|
127
128
|
- lib/oauth2/mac_token.rb
|
@@ -154,9 +155,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
155
|
version: 1.3.5
|
155
156
|
requirements: []
|
156
157
|
rubyforge_project:
|
157
|
-
rubygems_version: 2.2
|
158
|
+
rubygems_version: 2.5.2
|
158
159
|
signing_key:
|
159
160
|
specification_version: 4
|
160
161
|
summary: A Ruby wrapper for the OAuth 2.0 protocol.
|
161
162
|
test_files: []
|
162
|
-
has_rdoc:
|