oauth2 2.0.25 → 2.1.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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +139 -3
- data/README.md +64 -83
- data/lib/oauth2/access_token.rb +7 -2
- data/lib/oauth2/client.rb +42 -12
- data/lib/oauth2/sanitized_log_formatter.rb +198 -0
- data/lib/oauth2/version.rb +4 -1
- data/lib/oauth2.rb +11 -1
- data/sig/oauth2.rbs +206 -0
- data.tar.gz.sig +0 -0
- metadata +40 -61
- metadata.gz.sig +0 -0
- data/CITATION.cff +0 -20
- data/CODE_OF_CONDUCT.md +0 -134
- data/CONTRIBUTING.md +0 -275
- data/FUNDING.md +0 -70
- data/MIT.md +0 -21
- data/RUBOCOP.md +0 -71
- data/SECURITY.md +0 -21
- data/certs/pboling.pem +0 -27
- data/sig/oauth2/access_token.rbs +0 -25
- data/sig/oauth2/authenticator.rbs +0 -22
- data/sig/oauth2/client.rbs +0 -52
- data/sig/oauth2/error.rbs +0 -8
- data/sig/oauth2/filtered_attributes.rbs +0 -11
- data/sig/oauth2/response.rbs +0 -18
- data/sig/oauth2/sanitized_logger.rbs +0 -32
- data/sig/oauth2/strategy.rbs +0 -34
- data/sig/oauth2/thing_filter.rbs +0 -10
- data/sig/oauth2/version.rbs +0 -6
data/lib/oauth2/client.rb
CHANGED
|
@@ -66,6 +66,9 @@ module OAuth2
|
|
|
66
66
|
raise_errors: true,
|
|
67
67
|
logger: ::Logger.new($stdout),
|
|
68
68
|
access_token_class: AccessToken,
|
|
69
|
+
# Default changed from true to false in 2.1.0 for security.
|
|
70
|
+
# Cross-origin redirects are now rejected before credentials are replayed.
|
|
71
|
+
allow_cross_origin_redirects: false,
|
|
69
72
|
}.merge(opts)
|
|
70
73
|
@options[:connection_opts][:ssl] = ssl if ssl
|
|
71
74
|
end
|
|
@@ -491,13 +494,29 @@ module OAuth2
|
|
|
491
494
|
def sanitize_redirect_options(req_opts, current_location, next_location)
|
|
492
495
|
return req_opts unless cross_origin_redirect?(current_location, next_location)
|
|
493
496
|
|
|
494
|
-
|
|
495
|
-
|
|
497
|
+
unless options[:allow_cross_origin_redirects]
|
|
498
|
+
raise OAuth2::Error.new(
|
|
499
|
+
"error" => "cross_origin_redirect_blocked",
|
|
500
|
+
"error_description" => "Cross-origin redirect blocked: #{current_location.scheme}://#{current_location.host} -> #{next_location.scheme}://#{next_location.host}. " \
|
|
501
|
+
"Set allow_cross_origin_redirects: true to allow (deprecated)."
|
|
502
|
+
)
|
|
503
|
+
end
|
|
496
504
|
|
|
497
505
|
safe_opts = req_opts.dup
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
506
|
+
|
|
507
|
+
[:headers, "headers"].each do |key|
|
|
508
|
+
headers = safe_opts[key]
|
|
509
|
+
next unless headers && headers.any? { |header, _value| authorization_header?(header) }
|
|
510
|
+
|
|
511
|
+
safe_headers = headers.dup
|
|
512
|
+
safe_headers.delete_if { |header, _value| authorization_header?(header) }
|
|
513
|
+
safe_opts[key] = safe_headers
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
safe_opts.delete(:body)
|
|
517
|
+
safe_opts.delete("body")
|
|
518
|
+
safe_opts.delete(:params)
|
|
519
|
+
safe_opts.delete("params")
|
|
501
520
|
safe_opts
|
|
502
521
|
end
|
|
503
522
|
|
|
@@ -600,17 +619,28 @@ module OAuth2
|
|
|
600
619
|
#
|
|
601
620
|
# @api private
|
|
602
621
|
def build_access_token_legacy(response, access_token_opts, extract_access_token)
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
622
|
+
parsed = response.parsed
|
|
623
|
+
begin
|
|
624
|
+
extract_access_token.call(self, parsed.merge(access_token_opts))
|
|
625
|
+
rescue
|
|
626
|
+
# An error will be raised by the called if nil is returned and options[:raise_errors] is truthy, so this rescue is but temporary.
|
|
627
|
+
# Unfortunately, it does hide the real error, but this is deprecated legacy code,
|
|
628
|
+
# and this was effectively the long-standing pre-existing behavior, so there is little point in changing it.
|
|
629
|
+
nil
|
|
630
|
+
end
|
|
609
631
|
end
|
|
610
632
|
|
|
611
633
|
def oauth_debug_logging(builder)
|
|
612
634
|
if OAuth2::OAUTH_DEBUG
|
|
613
635
|
config = OAuth2.config
|
|
636
|
+
logger_options = {bodies: true}
|
|
637
|
+
# Faraday >= 1.0 supports pluggable formatters; use ours to redact
|
|
638
|
+
# structured (Hash/Array) bodies before Faraday renders them.
|
|
639
|
+
if defined?(OAuth2::SanitizedLogFormatter)
|
|
640
|
+
# Faraday instantiates the formatter with (logger:, options:); the
|
|
641
|
+
# formatter snapshots redaction config from OAuth2.config at that point.
|
|
642
|
+
logger_options[:formatter] = OAuth2::SanitizedLogFormatter
|
|
643
|
+
end
|
|
614
644
|
builder.response(
|
|
615
645
|
:logger,
|
|
616
646
|
OAuth2::AUTH_SANITIZER::SanitizedLogger.new(
|
|
@@ -618,7 +648,7 @@ module OAuth2
|
|
|
618
648
|
filtered_keys: config[:filtered_debug_keys],
|
|
619
649
|
label: config[:filtered_label]
|
|
620
650
|
),
|
|
621
|
-
|
|
651
|
+
**logger_options
|
|
622
652
|
)
|
|
623
653
|
end
|
|
624
654
|
end
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "faraday"
|
|
4
|
+
|
|
5
|
+
begin
|
|
6
|
+
require "faraday/logging/formatter"
|
|
7
|
+
rescue LoadError
|
|
8
|
+
# Faraday 0.x has no pluggable logging formatter; the text sanitizer remains
|
|
9
|
+
# active through OAuth2::AUTH_SANITIZER::SanitizedLogger.
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module OAuth2
|
|
13
|
+
if defined?(Faraday::Logging::Formatter) # Faraday >= 1.0
|
|
14
|
+
# Faraday logging formatter that redacts sensitive values from Hash and Array
|
|
15
|
+
# request/response bodies BEFORE Faraday renders them (via `pretty_inspect`).
|
|
16
|
+
#
|
|
17
|
+
# Text-level sanitization ({OAuth2::AUTH_SANITIZER::SanitizedLogger}) remains as a
|
|
18
|
+
# second layer for headers, query strings, and already-serialized bodies.
|
|
19
|
+
#
|
|
20
|
+
# Redaction rules:
|
|
21
|
+
# - keys matching any filtered key (case-insensitive) are redacted, nested at any depth
|
|
22
|
+
# - the authorization `code` is redacted only in an authorization_code grant context,
|
|
23
|
+
# detected from the request URL query or the body itself, so non-secret codes
|
|
24
|
+
# (e.g. error codes) are preserved
|
|
25
|
+
# - cyclic structures are tolerated
|
|
26
|
+
#
|
|
27
|
+
# Requires Faraday >= 1.0 (Faraday::Logging::Formatter). On Faraday 0.17 this
|
|
28
|
+
# class is not defined and the caller falls back to text-level sanitization only.
|
|
29
|
+
#
|
|
30
|
+
# @api private
|
|
31
|
+
class SanitizedLogFormatter < Faraday::Logging::Formatter
|
|
32
|
+
# Keys redacted only in an authorization_code grant context.
|
|
33
|
+
CONTEXTUAL_KEYS = %w[code].freeze
|
|
34
|
+
|
|
35
|
+
# Faraday instantiates formatters itself with (logger:, options:), so the
|
|
36
|
+
# redaction configuration falls back to the current OAuth2.config values.
|
|
37
|
+
#
|
|
38
|
+
# @param filtered_keys [Array<String>, nil] key names to redact unconditionally
|
|
39
|
+
# @param label [String, nil] replacement label
|
|
40
|
+
# @param options [Hash] Faraday formatter options
|
|
41
|
+
def initialize(filtered_keys: nil, label: nil, **options)
|
|
42
|
+
super(**options)
|
|
43
|
+
config = OAuth2.config
|
|
44
|
+
@filtered_keys = (filtered_keys || config[:filtered_debug_keys]).map { |key| key.to_s.downcase }.freeze
|
|
45
|
+
@label = (label || config[:filtered_label]).to_s
|
|
46
|
+
@code_context = false
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Log the request, detecting authorization_code context from the URL and body.
|
|
50
|
+
#
|
|
51
|
+
# @param env [Faraday::Env] request environment
|
|
52
|
+
def request(env)
|
|
53
|
+
with_code_context(env) do
|
|
54
|
+
if @code_context && env.respond_to?(:url) && env.url && env.url.query.to_s.include?("code=")
|
|
55
|
+
# Log a sanitized COPY of the env; the real request must keep its URL.
|
|
56
|
+
sanitized_env = env.dup
|
|
57
|
+
sanitized_env.url = sanitize_url_code(env.url)
|
|
58
|
+
super(sanitized_env)
|
|
59
|
+
else
|
|
60
|
+
super
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Log the response, detecting authorization_code context from the URL and body.
|
|
66
|
+
#
|
|
67
|
+
# @param env [Faraday::Env] response environment
|
|
68
|
+
def response(env)
|
|
69
|
+
with_code_context(env) { super }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Redact structured bodies before rendering; leave everything else to the parent.
|
|
73
|
+
#
|
|
74
|
+
# @param body [Object] request or response body
|
|
75
|
+
# @return [String] rendered body for logging
|
|
76
|
+
def dump_body(body)
|
|
77
|
+
case body
|
|
78
|
+
when Hash, Array
|
|
79
|
+
super(redact_structured(body, seen: {}, code_sensitive: @code_context))
|
|
80
|
+
when String
|
|
81
|
+
super(@code_context ? redact_code_in_string(body) : body)
|
|
82
|
+
else
|
|
83
|
+
super
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
# Redact the authorization `code` value in URL-encoded, JSON, and
|
|
90
|
+
# Hash#inspect-shaped string bodies. Only called in authorization_code
|
|
91
|
+
# grant context, so `code` always names the credential here.
|
|
92
|
+
def redact_code_in_string(body)
|
|
93
|
+
body.dup.scrub.
|
|
94
|
+
gsub(/\bcode=[^&\s"']+/, "code=#{@label}").
|
|
95
|
+
gsub(/("code"\s*:\s*")[^"]*(")/i) { "#{$1}#{@label}#{$2}" }.
|
|
96
|
+
gsub(/(("code"|code:)\s*=>?\s*")[^"]*(")/i) { "#{$1}#{@label}#{$3}" }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Redact the `code` query parameter of a URL, returning a new URI.
|
|
100
|
+
def sanitize_url_code(url)
|
|
101
|
+
sanitized = url.dup
|
|
102
|
+
pairs = sanitized.query.to_s.tr("+", " ").split("&").map do |pair|
|
|
103
|
+
pair.start_with?("code=") ? "code=#{@label}" : pair
|
|
104
|
+
end
|
|
105
|
+
sanitized.query = pairs.join("&")
|
|
106
|
+
sanitized
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def with_code_context(env)
|
|
110
|
+
previous = @code_context
|
|
111
|
+
@code_context = previous || authorization_code_request?(env)
|
|
112
|
+
yield
|
|
113
|
+
ensure
|
|
114
|
+
@code_context = previous
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def authorization_code_request?(env)
|
|
118
|
+
url = env.respond_to?(:url) ? env.url : nil
|
|
119
|
+
if url
|
|
120
|
+
query_pairs = url.query.to_s.tr("+", " ").split("&")
|
|
121
|
+
return true if query_pairs.any? { |pair| pair == "grant_type=authorization_code" }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
body = env.respond_to?(:body) ? env.body : nil
|
|
125
|
+
case body
|
|
126
|
+
when String
|
|
127
|
+
scrubbed = body.dup.scrub
|
|
128
|
+
scrubbed.match?(/grant_type=authorization_code/) ||
|
|
129
|
+
scrubbed.match?(/grant(?:\\u005f|_)type\\?"?\s*:\s*\\?"authorization_code/)
|
|
130
|
+
else
|
|
131
|
+
authorization_code_context?(body) || authorization_code_pairs_context?(body)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def redact_structured(node, seen:, code_sensitive:)
|
|
136
|
+
return node if node.nil?
|
|
137
|
+
|
|
138
|
+
case node
|
|
139
|
+
when Hash
|
|
140
|
+
object_id = node.object_id
|
|
141
|
+
return seen[object_id] if seen.key?(object_id)
|
|
142
|
+
|
|
143
|
+
copy = {}
|
|
144
|
+
seen[object_id] = copy
|
|
145
|
+
code_sensitive ||= authorization_code_context?(node)
|
|
146
|
+
node.each do |key, value|
|
|
147
|
+
copy[key] = if redact_key?(key, redact_code: code_sensitive)
|
|
148
|
+
@label
|
|
149
|
+
else
|
|
150
|
+
redact_structured(value, seen: seen, code_sensitive: code_sensitive)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
copy
|
|
154
|
+
when Array
|
|
155
|
+
object_id = node.object_id
|
|
156
|
+
return seen[object_id] if seen.key?(object_id)
|
|
157
|
+
|
|
158
|
+
copy = []
|
|
159
|
+
seen[object_id] = copy
|
|
160
|
+
code_sensitive ||= authorization_code_pairs_context?(node)
|
|
161
|
+
if pair_array?(node)
|
|
162
|
+
node.each do |pair|
|
|
163
|
+
copy << if redact_key?(pair[0], redact_code: code_sensitive)
|
|
164
|
+
[pair[0], @label]
|
|
165
|
+
else
|
|
166
|
+
[pair[0], redact_structured(pair[1], seen: seen, code_sensitive: code_sensitive)]
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
else
|
|
170
|
+
node.each { |element| copy << redact_structured(element, seen: seen, code_sensitive: code_sensitive) }
|
|
171
|
+
end
|
|
172
|
+
copy
|
|
173
|
+
else
|
|
174
|
+
node
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def redact_key?(key, redact_code:)
|
|
179
|
+
name = key.to_s.downcase
|
|
180
|
+
return true if @filtered_keys.include?(name)
|
|
181
|
+
|
|
182
|
+
redact_code && CONTEXTUAL_KEYS.include?(name)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def authorization_code_context?(node)
|
|
186
|
+
node.is_a?(Hash) && node.any? { |key, value| key.to_s == "grant_type" && value.to_s == "authorization_code" }
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def pair_array?(node)
|
|
190
|
+
node.is_a?(Array) && !node.empty? && node.all? { |element| element.is_a?(Array) && element.length == 2 }
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def authorization_code_pairs_context?(node)
|
|
194
|
+
pair_array?(node) && node.any? { |pair| pair[0].to_s == "grant_type" && pair[1].to_s == "authorization_code" }
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
data/lib/oauth2/version.rb
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module OAuth2
|
|
4
|
+
# Version namespace for this gem.
|
|
4
5
|
module Version
|
|
5
|
-
|
|
6
|
+
# Current gem version.
|
|
7
|
+
VERSION = "2.1.0"
|
|
6
8
|
end
|
|
9
|
+
# Current gem version exposed at the traditional constant location.
|
|
7
10
|
VERSION = Version::VERSION # Traditional Constant Location
|
|
8
11
|
end
|
data/lib/oauth2.rb
CHANGED
|
@@ -9,9 +9,9 @@ require "snaky_hash"
|
|
|
9
9
|
require "version_gem"
|
|
10
10
|
|
|
11
11
|
# includes gem files
|
|
12
|
-
require_relative "oauth2/version"
|
|
13
12
|
require_relative "oauth2/auth_sanitizer"
|
|
14
13
|
require_relative "oauth2/filtered_attributes"
|
|
14
|
+
require_relative "oauth2/sanitized_log_formatter"
|
|
15
15
|
require_relative "oauth2/error"
|
|
16
16
|
require_relative "oauth2/authenticator"
|
|
17
17
|
require_relative "oauth2/client"
|
|
@@ -23,6 +23,7 @@ require_relative "oauth2/strategy/client_credentials"
|
|
|
23
23
|
require_relative "oauth2/strategy/assertion"
|
|
24
24
|
require_relative "oauth2/access_token"
|
|
25
25
|
require_relative "oauth2/response"
|
|
26
|
+
require_relative "oauth2/version"
|
|
26
27
|
|
|
27
28
|
# The namespace of this library
|
|
28
29
|
#
|
|
@@ -67,6 +68,14 @@ module OAuth2
|
|
|
67
68
|
assertion
|
|
68
69
|
code_verifier
|
|
69
70
|
token
|
|
71
|
+
password
|
|
72
|
+
client_assertion
|
|
73
|
+
device_code
|
|
74
|
+
subject_token
|
|
75
|
+
actor_token
|
|
76
|
+
accessToken
|
|
77
|
+
refreshToken
|
|
78
|
+
idToken
|
|
70
79
|
]
|
|
71
80
|
)
|
|
72
81
|
|
|
@@ -98,6 +107,7 @@ end
|
|
|
98
107
|
OAuth2::AUTH_SANITIZER.filtered_label_provider = -> { OAuth2.config[:filtered_label] }
|
|
99
108
|
|
|
100
109
|
# Extend OAuth2::Version with VersionGem helpers to provide semantic version helpers.
|
|
110
|
+
|
|
101
111
|
OAuth2::Version.class_eval do
|
|
102
112
|
extend VersionGem::Basic
|
|
103
113
|
end
|
data/sig/oauth2.rbs
CHANGED
|
@@ -6,4 +6,210 @@ module OAuth2
|
|
|
6
6
|
|
|
7
7
|
def self.config: () -> untyped
|
|
8
8
|
def self.configure: () { (untyped) -> void } -> void
|
|
9
|
+
module Version
|
|
10
|
+
VERSION: String
|
|
11
|
+
end
|
|
12
|
+
VERSION: String
|
|
13
|
+
class AccessToken
|
|
14
|
+
def self.from_hash: (OAuth2::Client, Hash[untyped, untyped]) -> OAuth2::AccessToken
|
|
15
|
+
def self.from_kvform: (OAuth2::Client, String) -> OAuth2::AccessToken
|
|
16
|
+
|
|
17
|
+
def initialize: (OAuth2::Client, String, ?Hash[Symbol, untyped]) -> void
|
|
18
|
+
def []: (String | Symbol) -> untyped
|
|
19
|
+
def expires?: () -> bool
|
|
20
|
+
def expired?: () -> bool
|
|
21
|
+
def refresh: (?Hash[untyped, untyped], ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::AccessToken
|
|
22
|
+
def revoke: (?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
|
|
23
|
+
def to_hash: () -> Hash[Symbol, untyped]
|
|
24
|
+
def request: (Symbol, String, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
|
|
25
|
+
def get: (String, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
|
|
26
|
+
def post: (String, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
|
|
27
|
+
def put: (String, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
|
|
28
|
+
def patch: (String, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
|
|
29
|
+
def delete: (String, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
|
|
30
|
+
def headers: () -> Hash[String, String]
|
|
31
|
+
def configure_authentication!: (Hash[Symbol, untyped], Symbol) -> void
|
|
32
|
+
def convert_expires_at: (untyped) -> (Time | Integer | nil)
|
|
33
|
+
|
|
34
|
+
attr_accessor response: OAuth2::Response
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class Authenticator
|
|
38
|
+
include OAuth2::FilteredAttributes
|
|
39
|
+
|
|
40
|
+
attr_reader mode: (Symbol | String)
|
|
41
|
+
attr_reader id: String?
|
|
42
|
+
attr_reader secret: String?
|
|
43
|
+
|
|
44
|
+
def initialize: (String? id, String? secret, (Symbol | String) mode) -> void
|
|
45
|
+
|
|
46
|
+
def apply: (Hash[untyped, untyped]) -> Hash[untyped, untyped]
|
|
47
|
+
|
|
48
|
+
def self.encode_basic_auth: (String, String) -> String
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def apply_params_auth: (Hash[untyped, untyped]) -> Hash[untyped, untyped]
|
|
53
|
+
def apply_client_id: (Hash[untyped, untyped]) -> Hash[untyped, untyped]
|
|
54
|
+
def apply_basic_auth: (Hash[untyped, untyped]) -> Hash[untyped, untyped]
|
|
55
|
+
def basic_auth_header: () -> Hash[String, String]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class Client
|
|
59
|
+
RESERVED_REQ_KEYS: Array[String]
|
|
60
|
+
RESERVED_PARAM_KEYS: Array[String]
|
|
61
|
+
|
|
62
|
+
include OAuth2::FilteredAttributes
|
|
63
|
+
|
|
64
|
+
attr_reader id: String
|
|
65
|
+
attr_reader secret: String
|
|
66
|
+
attr_reader site: String?
|
|
67
|
+
attr_accessor options: Hash[Symbol, untyped]
|
|
68
|
+
attr_writer connection: untyped
|
|
69
|
+
|
|
70
|
+
def initialize: (String client_id, String client_secret, ?Hash[Symbol, untyped]) { (untyped) -> void } -> void
|
|
71
|
+
|
|
72
|
+
def site=: (String) -> String
|
|
73
|
+
|
|
74
|
+
def connection: () -> untyped
|
|
75
|
+
|
|
76
|
+
def authorize_url: (?Hash[untyped, untyped]) -> String
|
|
77
|
+
def token_url: (?Hash[untyped, untyped]) -> String
|
|
78
|
+
def revoke_url: (?Hash[untyped, untyped]) -> String
|
|
79
|
+
|
|
80
|
+
def request: (Symbol verb, String url, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
|
|
81
|
+
|
|
82
|
+
def get_token: (Hash[untyped, untyped] params, ?Hash[Symbol, untyped] access_token_opts, ?Proc) { (Hash[Symbol, untyped]) -> void } -> (OAuth2::AccessToken | nil)
|
|
83
|
+
|
|
84
|
+
def revoke_token: (String token, ?String token_type_hint, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
|
|
85
|
+
|
|
86
|
+
def http_method: () -> Symbol
|
|
87
|
+
|
|
88
|
+
def auth_code: () -> OAuth2::Strategy::AuthCode
|
|
89
|
+
def implicit: () -> OAuth2::Strategy::Implicit
|
|
90
|
+
def password: () -> OAuth2::Strategy::Password
|
|
91
|
+
def client_credentials: () -> OAuth2::Strategy::ClientCredentials
|
|
92
|
+
def assertion: () -> OAuth2::Strategy::Assertion
|
|
93
|
+
|
|
94
|
+
def redirection_params: () -> Hash[String, String]
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
|
|
98
|
+
def params_to_req_opts: (Hash[untyped, untyped]) -> Hash[Symbol, untyped]
|
|
99
|
+
def parse_snaky_params_headers: (Hash[untyped, untyped]) -> [Symbol, bool, untyped, (Symbol | nil), Hash[untyped, untyped], Hash[String, String]]
|
|
100
|
+
def execute_request: (Symbol verb, String url, ?Hash[Symbol, untyped]) { (Faraday::Request) -> void } -> OAuth2::Response
|
|
101
|
+
def authenticator: () -> OAuth2::Authenticator
|
|
102
|
+
def parse_response_legacy: (OAuth2::Response, Hash[Symbol, untyped], Proc) -> (OAuth2::AccessToken | nil)
|
|
103
|
+
def parse_response: (OAuth2::Response, Hash[Symbol, untyped]) -> (OAuth2::AccessToken | nil)
|
|
104
|
+
def build_access_token: (OAuth2::Response, Hash[Symbol, untyped], untyped) -> OAuth2::AccessToken
|
|
105
|
+
def build_access_token_legacy: (OAuth2::Response, Hash[Symbol, untyped], Proc) -> (OAuth2::AccessToken | nil)
|
|
106
|
+
def oauth_debug_logging: (untyped) -> void
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
class Error < StandardError
|
|
110
|
+
def initialize: (OAuth2::Response) -> void
|
|
111
|
+
def code: () -> (String | Integer | nil)
|
|
112
|
+
def description: () -> (String | nil)
|
|
113
|
+
def response: () -> OAuth2::Response
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
module FilteredAttributes
|
|
117
|
+
module InitializerMethods
|
|
118
|
+
def initialize: (*untyped args) { () -> untyped } -> untyped
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def self.included: (untyped) -> untyped
|
|
122
|
+
def filtered_attributes: (*(String | Symbol)) -> void
|
|
123
|
+
def thing_filter: () -> OAuth2::ThingFilter
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
class Response
|
|
127
|
+
DEFAULT_OPTIONS: Hash[Symbol, untyped]
|
|
128
|
+
|
|
129
|
+
def self.register_parser: (Symbol key, (Array[String] | String) mime_types) { (String) -> untyped } -> void
|
|
130
|
+
|
|
131
|
+
def initialize: (untyped response, parse: Symbol?, snaky: bool?, snaky_hash_klass: untyped?, options: Hash[Symbol, untyped]?) -> void
|
|
132
|
+
def headers: () -> Hash[untyped, untyped]
|
|
133
|
+
def status: () -> Integer
|
|
134
|
+
def body: () -> String
|
|
135
|
+
def parsed: () -> untyped
|
|
136
|
+
def content_type: () -> (String | nil)
|
|
137
|
+
def parser: () -> (untyped | nil)
|
|
138
|
+
|
|
139
|
+
attr_reader response: untyped
|
|
140
|
+
attr_accessor options: Hash[Symbol, untyped]
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
class SanitizedLogger
|
|
144
|
+
def initialize: (untyped logger) -> void
|
|
145
|
+
|
|
146
|
+
def add: (untyped severity, ?untyped message, ?untyped progname) { () -> untyped } -> untyped
|
|
147
|
+
def <<: (String message) -> untyped
|
|
148
|
+
def debug: (?untyped progname) { () -> untyped } -> untyped
|
|
149
|
+
def info: (?untyped progname) { () -> untyped } -> untyped
|
|
150
|
+
def warn: (?untyped progname) { () -> untyped } -> untyped
|
|
151
|
+
def error: (?untyped progname) { () -> untyped } -> untyped
|
|
152
|
+
def fatal: (?untyped progname) { () -> untyped } -> untyped
|
|
153
|
+
def unknown: (?untyped progname) { () -> untyped } -> untyped
|
|
154
|
+
def close: () -> void
|
|
155
|
+
def formatter: () -> untyped
|
|
156
|
+
def formatter=: (untyped formatter) -> void
|
|
157
|
+
def level: () -> untyped
|
|
158
|
+
def level=: (untyped level) -> void
|
|
159
|
+
def progname: () -> untyped
|
|
160
|
+
def progname=: (untyped progname) -> void
|
|
161
|
+
def respond_to_missing?: (Symbol method_name, ?bool include_private) -> bool
|
|
162
|
+
def method_missing: (Symbol method_name, *untyped args) { () -> untyped } -> untyped
|
|
163
|
+
|
|
164
|
+
private
|
|
165
|
+
|
|
166
|
+
def log: (Symbol level, ?untyped progname) { () -> untyped } -> untyped
|
|
167
|
+
def sanitize: (untyped message) -> untyped
|
|
168
|
+
def thing_filter: () -> OAuth2::ThingFilter
|
|
169
|
+
def sanitize_authorization_header: (String message) -> String
|
|
170
|
+
def sanitize_json_pairs: (String message) -> String
|
|
171
|
+
def sanitize_form_and_query_pairs: (String message) -> String
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
module Strategy
|
|
175
|
+
class Base
|
|
176
|
+
def initialize: (OAuth2::Client) -> void
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
class AuthCode < Base
|
|
180
|
+
def authorize_params: (?Hash[untyped, untyped]) -> Hash[untyped, untyped]
|
|
181
|
+
def authorize_url: (?Hash[untyped, untyped]) -> String
|
|
182
|
+
def get_token: (String, ?Hash[untyped, untyped], ?Hash[Symbol, untyped]) -> OAuth2::AccessToken
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
class Implicit < Base
|
|
186
|
+
def authorize_params: (?Hash[untyped, untyped]) -> Hash[untyped, untyped]
|
|
187
|
+
def authorize_url: (?Hash[untyped, untyped]) -> String
|
|
188
|
+
def get_token: (*untyped) -> void
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
class Password < Base
|
|
192
|
+
def authorize_url: () -> void
|
|
193
|
+
def get_token: (String, String, ?Hash[untyped, untyped], ?Hash[Symbol, untyped]) -> OAuth2::AccessToken
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
class ClientCredentials < Base
|
|
197
|
+
def authorize_url: () -> void
|
|
198
|
+
def get_token: (?Hash[untyped, untyped], ?Hash[Symbol, untyped]) -> OAuth2::AccessToken
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
class Assertion < Base
|
|
202
|
+
def authorize_url: () -> void
|
|
203
|
+
def get_token: (Hash[untyped, untyped], Hash[Symbol, untyped], ?Hash[Symbol, untyped], ?Hash[Symbol, untyped]) -> OAuth2::AccessToken
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
class ThingFilter
|
|
208
|
+
attr_reader things: Array[String]
|
|
209
|
+
attr_reader label: String
|
|
210
|
+
|
|
211
|
+
def initialize: (Enumerable[untyped] things, label: String) -> void
|
|
212
|
+
def filtered?: (untyped thing_name) -> bool
|
|
213
|
+
def pattern_source: () -> String
|
|
214
|
+
end
|
|
9
215
|
end
|
data.tar.gz.sig
CHANGED
|
Binary file
|