oauth2 1.4.9 → 2.0.17

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +706 -88
  4. data/CITATION.cff +20 -0
  5. data/CODE_OF_CONDUCT.md +24 -23
  6. data/CONTRIBUTING.md +229 -0
  7. data/FUNDING.md +77 -0
  8. data/{LICENSE → LICENSE.txt} +2 -2
  9. data/OIDC.md +158 -0
  10. data/README.md +1513 -251
  11. data/REEK +0 -0
  12. data/RUBOCOP.md +71 -0
  13. data/SECURITY.md +21 -0
  14. data/lib/oauth2/access_token.rb +276 -39
  15. data/lib/oauth2/authenticator.rb +45 -8
  16. data/lib/oauth2/client.rb +406 -129
  17. data/lib/oauth2/error.rb +59 -24
  18. data/lib/oauth2/filtered_attributes.rb +52 -0
  19. data/lib/oauth2/response.rb +127 -36
  20. data/lib/oauth2/strategy/assertion.rb +68 -40
  21. data/lib/oauth2/strategy/auth_code.rb +25 -4
  22. data/lib/oauth2/strategy/client_credentials.rb +3 -3
  23. data/lib/oauth2/strategy/implicit.rb +17 -2
  24. data/lib/oauth2/strategy/password.rb +14 -4
  25. data/lib/oauth2/version.rb +1 -59
  26. data/lib/oauth2.rb +79 -12
  27. data/sig/oauth2/access_token.rbs +25 -0
  28. data/sig/oauth2/authenticator.rbs +22 -0
  29. data/sig/oauth2/client.rbs +52 -0
  30. data/sig/oauth2/error.rbs +8 -0
  31. data/sig/oauth2/filtered_attributes.rbs +6 -0
  32. data/sig/oauth2/response.rbs +18 -0
  33. data/sig/oauth2/strategy.rbs +34 -0
  34. data/sig/oauth2/version.rbs +5 -0
  35. data/sig/oauth2.rbs +9 -0
  36. data.tar.gz.sig +0 -0
  37. metadata +336 -89
  38. metadata.gz.sig +0 -0
  39. data/lib/oauth2/mac_token.rb +0 -130
  40. data/spec/fixtures/README.md +0 -11
  41. data/spec/fixtures/RS256/jwtRS256.key +0 -51
  42. data/spec/fixtures/RS256/jwtRS256.key.pub +0 -14
  43. data/spec/helper.rb +0 -33
  44. data/spec/oauth2/access_token_spec.rb +0 -218
  45. data/spec/oauth2/authenticator_spec.rb +0 -86
  46. data/spec/oauth2/client_spec.rb +0 -556
  47. data/spec/oauth2/mac_token_spec.rb +0 -122
  48. data/spec/oauth2/response_spec.rb +0 -96
  49. data/spec/oauth2/strategy/assertion_spec.rb +0 -113
  50. data/spec/oauth2/strategy/auth_code_spec.rb +0 -108
  51. data/spec/oauth2/strategy/base_spec.rb +0 -7
  52. data/spec/oauth2/strategy/client_credentials_spec.rb +0 -71
  53. data/spec/oauth2/strategy/implicit_spec.rb +0 -28
  54. data/spec/oauth2/strategy/password_spec.rb +0 -58
  55. data/spec/oauth2/version_spec.rb +0 -23
@@ -4,13 +4,21 @@ module OAuth2
4
4
  module Strategy
5
5
  # The Resource Owner Password Credentials Authorization Strategy
6
6
  #
7
+ # IMPORTANT (OAuth 2.1): The Resource Owner Password Credentials grant is omitted in OAuth 2.1.
8
+ # It remains here for backward compatibility with OAuth 2.0 providers. Prefer Authorization Code + PKCE.
9
+ #
10
+ # References:
11
+ # - OAuth 2.1 draft: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13
12
+ # - Okta explainer: https://developer.okta.com/blog/2019/12/13/oauth-2-1-how-many-rfcs
13
+ # - FusionAuth blog: https://fusionauth.io/blog/2020/04/15/whats-new-in-oauth-2-1
14
+ #
7
15
  # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.3
8
16
  class Password < Base
9
17
  # Not used for this strategy
10
18
  #
11
19
  # @raise [NotImplementedError]
12
20
  def authorize_url
13
- raise(NotImplementedError, 'The authorization endpoint is not used in this strategy')
21
+ raise(NotImplementedError, "The authorization endpoint is not used in this strategy")
14
22
  end
15
23
 
16
24
  # Retrieve an access token given the specified End User username and password.
@@ -19,9 +27,11 @@ module OAuth2
19
27
  # @param [String] password the End User password
20
28
  # @param [Hash] params additional params
21
29
  def get_token(username, password, params = {}, opts = {})
22
- params = {'grant_type' => 'password',
23
- 'username' => username,
24
- 'password' => password}.merge(params)
30
+ params = {
31
+ "grant_type" => "password",
32
+ "username" => username,
33
+ "password" => password,
34
+ }.merge(params)
25
35
  @client.get_token(params, opts)
26
36
  end
27
37
  end
@@ -2,64 +2,6 @@
2
2
 
3
3
  module OAuth2
4
4
  module Version
5
- VERSION = to_s
6
-
7
- module_function
8
-
9
- # The major version
10
- #
11
- # @return [Integer]
12
- def major
13
- 1
14
- end
15
-
16
- # The minor version
17
- #
18
- # @return [Integer]
19
- def minor
20
- 4
21
- end
22
-
23
- # The patch version
24
- #
25
- # @return [Integer]
26
- def patch
27
- 9
28
- end
29
-
30
- # The pre-release version, if any
31
- #
32
- # @return [String, NilClass]
33
- def pre
34
- nil
35
- end
36
-
37
- # The version number as a hash
38
- #
39
- # @return [Hash]
40
- def to_h
41
- {
42
- :major => major,
43
- :minor => minor,
44
- :patch => patch,
45
- :pre => pre,
46
- }
47
- end
48
-
49
- # The version number as an array
50
- #
51
- # @return [Array]
52
- def to_a
53
- [major, minor, patch, pre].compact
54
- end
55
-
56
- # The version number as a string
57
- #
58
- # @return [String]
59
- def to_s
60
- v = [major, minor, patch].compact.join('.')
61
- v += "-#{pre}" if pre
62
- v
63
- end
5
+ VERSION = "2.0.17"
64
6
  end
65
7
  end
data/lib/oauth2.rb CHANGED
@@ -1,14 +1,81 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'oauth2/error'
4
- require 'oauth2/authenticator'
5
- require 'oauth2/client'
6
- require 'oauth2/strategy/base'
7
- require 'oauth2/strategy/auth_code'
8
- require 'oauth2/strategy/implicit'
9
- require 'oauth2/strategy/password'
10
- require 'oauth2/strategy/client_credentials'
11
- require 'oauth2/strategy/assertion'
12
- require 'oauth2/access_token'
13
- require 'oauth2/mac_token'
14
- require 'oauth2/response'
3
+ # includes modules from stdlib
4
+ require "cgi"
5
+ require "time"
6
+
7
+ # third party gems
8
+ require "snaky_hash"
9
+ require "version_gem"
10
+
11
+ # includes gem files
12
+ require_relative "oauth2/version"
13
+ require_relative "oauth2/filtered_attributes"
14
+ require_relative "oauth2/error"
15
+ require_relative "oauth2/authenticator"
16
+ require_relative "oauth2/client"
17
+ require_relative "oauth2/strategy/base"
18
+ require_relative "oauth2/strategy/auth_code"
19
+ require_relative "oauth2/strategy/implicit"
20
+ require_relative "oauth2/strategy/password"
21
+ require_relative "oauth2/strategy/client_credentials"
22
+ require_relative "oauth2/strategy/assertion"
23
+ require_relative "oauth2/access_token"
24
+ require_relative "oauth2/response"
25
+
26
+ # The namespace of this library
27
+ #
28
+ # This module is the entry point and top-level namespace for the oauth2 gem.
29
+ # It exposes configuration, constants, and requires the primary public classes.
30
+ module OAuth2
31
+ # When true, enables verbose HTTP logging via Faraday's logger middleware.
32
+ # Controlled by the OAUTH_DEBUG environment variable. Any case-insensitive
33
+ # value equal to "true" will enable debugging.
34
+ #
35
+ # @return [Boolean]
36
+ OAUTH_DEBUG = ENV.fetch("OAUTH_DEBUG", "false").casecmp("true").zero?
37
+
38
+ # Default configuration values for the oauth2 library.
39
+ #
40
+ # @example Toggle warnings
41
+ # OAuth2.configure do |config|
42
+ # config[:silence_extra_tokens_warning] = false
43
+ # config[:silence_no_tokens_warning] = false
44
+ # end
45
+ #
46
+ # @return [SnakyHash::SymbolKeyed] A mutable Hash-like config with symbol keys
47
+ DEFAULT_CONFIG = SnakyHash::SymbolKeyed.new(
48
+ silence_extra_tokens_warning: true,
49
+ silence_no_tokens_warning: true,
50
+ )
51
+
52
+ # The current runtime configuration for the library.
53
+ #
54
+ # @return [SnakyHash::SymbolKeyed]
55
+ @config = DEFAULT_CONFIG.dup
56
+
57
+ class << self
58
+ # Access the current configuration.
59
+ #
60
+ # Prefer using {OAuth2.configure} to mutate configuration.
61
+ #
62
+ # @return [SnakyHash::SymbolKeyed]
63
+ attr_reader :config
64
+ end
65
+
66
+ # Configure global library behavior.
67
+ #
68
+ # Yields the mutable configuration object so callers can update settings.
69
+ #
70
+ # @yieldparam [SnakyHash::SymbolKeyed] config the configuration object
71
+ # @return [void]
72
+ def configure
73
+ yield @config
74
+ end
75
+ module_function :configure
76
+ end
77
+
78
+ # Extend OAuth2::Version with VersionGem helpers to provide semantic version helpers.
79
+ OAuth2::Version.class_eval do
80
+ extend VersionGem::Basic
81
+ end
@@ -0,0 +1,25 @@
1
+ module OAuth2
2
+ class AccessToken
3
+ def self.from_hash: (OAuth2::Client, Hash[untyped, untyped]) -> OAuth2::AccessToken
4
+ def self.from_kvform: (OAuth2::Client, String) -> OAuth2::AccessToken
5
+
6
+ def initialize: (OAuth2::Client, String, ?Hash[Symbol, untyped]) -> void
7
+ def []: (String | Symbol) -> untyped
8
+ def expires?: () -> bool
9
+ def expired?: () -> bool
10
+ def refresh: (?Hash[untyped, untyped], ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::AccessToken
11
+ def revoke: (?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
12
+ def to_hash: () -> Hash[Symbol, untyped]
13
+ def request: (Symbol, String, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
14
+ def get: (String, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
15
+ def post: (String, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
16
+ def put: (String, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
17
+ def patch: (String, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
18
+ def delete: (String, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
19
+ def headers: () -> Hash[String, String]
20
+ def configure_authentication!: (Hash[Symbol, untyped], Symbol) -> void
21
+ def convert_expires_at: (untyped) -> (Time | Integer | nil)
22
+
23
+ attr_accessor response: OAuth2::Response
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ module OAuth2
2
+ class Authenticator
3
+ include OAuth2::FilteredAttributes
4
+
5
+ attr_reader mode: (Symbol | String)
6
+ attr_reader id: String?
7
+ attr_reader secret: String?
8
+
9
+ def initialize: (String? id, String? secret, (Symbol | String) mode) -> void
10
+
11
+ def apply: (Hash[untyped, untyped]) -> Hash[untyped, untyped]
12
+
13
+ def self.encode_basic_auth: (String, String) -> String
14
+
15
+ private
16
+
17
+ def apply_params_auth: (Hash[untyped, untyped]) -> Hash[untyped, untyped]
18
+ def apply_client_id: (Hash[untyped, untyped]) -> Hash[untyped, untyped]
19
+ def apply_basic_auth: (Hash[untyped, untyped]) -> Hash[untyped, untyped]
20
+ def basic_auth_header: () -> Hash[String, String]
21
+ end
22
+ end
@@ -0,0 +1,52 @@
1
+ module OAuth2
2
+ class Client
3
+ RESERVED_REQ_KEYS: Array[String]
4
+ RESERVED_PARAM_KEYS: Array[String]
5
+
6
+ include OAuth2::FilteredAttributes
7
+
8
+ attr_reader id: String
9
+ attr_reader secret: String
10
+ attr_reader site: String?
11
+ attr_accessor options: Hash[Symbol, untyped]
12
+ attr_writer connection: untyped
13
+
14
+ def initialize: (String client_id, String client_secret, ?Hash[Symbol, untyped]) { (untyped) -> void } -> void
15
+
16
+ def site=: (String) -> String
17
+
18
+ def connection: () -> untyped
19
+
20
+ def authorize_url: (?Hash[untyped, untyped]) -> String
21
+ def token_url: (?Hash[untyped, untyped]) -> String
22
+ def revoke_url: (?Hash[untyped, untyped]) -> String
23
+
24
+ def request: (Symbol verb, String url, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
25
+
26
+ def get_token: (Hash[untyped, untyped] params, ?Hash[Symbol, untyped] access_token_opts, ?Proc) { (Hash[Symbol, untyped]) -> void } -> (OAuth2::AccessToken | nil)
27
+
28
+ def revoke_token: (String token, ?String token_type_hint, ?Hash[Symbol, untyped]) { (untyped) -> void } -> OAuth2::Response
29
+
30
+ def http_method: () -> Symbol
31
+
32
+ def auth_code: () -> OAuth2::Strategy::AuthCode
33
+ def implicit: () -> OAuth2::Strategy::Implicit
34
+ def password: () -> OAuth2::Strategy::Password
35
+ def client_credentials: () -> OAuth2::Strategy::ClientCredentials
36
+ def assertion: () -> OAuth2::Strategy::Assertion
37
+
38
+ def redirection_params: () -> Hash[String, String]
39
+
40
+ private
41
+
42
+ def params_to_req_opts: (Hash[untyped, untyped]) -> Hash[Symbol, untyped]
43
+ def parse_snaky_params_headers: (Hash[untyped, untyped]) -> [Symbol, bool, untyped, (Symbol | nil), Hash[untyped, untyped], Hash[String, String]]
44
+ def execute_request: (Symbol verb, String url, ?Hash[Symbol, untyped]) { (Faraday::Request) -> void } -> OAuth2::Response
45
+ def authenticator: () -> OAuth2::Authenticator
46
+ def parse_response_legacy: (OAuth2::Response, Hash[Symbol, untyped], Proc) -> (OAuth2::AccessToken | nil)
47
+ def parse_response: (OAuth2::Response, Hash[Symbol, untyped]) -> (OAuth2::AccessToken | nil)
48
+ def build_access_token: (OAuth2::Response, Hash[Symbol, untyped], untyped) -> OAuth2::AccessToken
49
+ def build_access_token_legacy: (OAuth2::Response, Hash[Symbol, untyped], Proc) -> (OAuth2::AccessToken | nil)
50
+ def oauth_debug_logging: (untyped) -> void
51
+ end
52
+ end
@@ -0,0 +1,8 @@
1
+ module OAuth2
2
+ class Error < StandardError
3
+ def initialize: (OAuth2::Response) -> void
4
+ def code: () -> (String | Integer | nil)
5
+ def description: () -> (String | nil)
6
+ def response: () -> OAuth2::Response
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ module OAuth2
2
+ module FilteredAttributes
3
+ def self.included: (untyped) -> untyped
4
+ def filtered_attributes: (*String) -> void
5
+ end
6
+ end
@@ -0,0 +1,18 @@
1
+ module OAuth2
2
+ class Response
3
+ DEFAULT_OPTIONS: Hash[Symbol, untyped]
4
+
5
+ def self.register_parser: (Symbol key, (Array[String] | String) mime_types) { (String) -> untyped } -> void
6
+
7
+ def initialize: (untyped response, parse: Symbol?, snaky: bool?, snaky_hash_klass: untyped?, options: Hash[Symbol, untyped]?) -> void
8
+ def headers: () -> Hash[untyped, untyped]
9
+ def status: () -> Integer
10
+ def body: () -> String
11
+ def parsed: () -> untyped
12
+ def content_type: () -> (String | nil)
13
+ def parser: () -> (untyped | nil)
14
+
15
+ attr_reader response: untyped
16
+ attr_accessor options: Hash[Symbol, untyped]
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ module OAuth2
2
+ module Strategy
3
+ class Base
4
+ def initialize: (OAuth2::Client) -> void
5
+ end
6
+
7
+ class AuthCode < Base
8
+ def authorize_params: (?Hash[untyped, untyped]) -> Hash[untyped, untyped]
9
+ def authorize_url: (?Hash[untyped, untyped]) -> String
10
+ def get_token: (String, ?Hash[untyped, untyped], ?Hash[Symbol, untyped]) -> OAuth2::AccessToken
11
+ end
12
+
13
+ class Implicit < Base
14
+ def authorize_params: (?Hash[untyped, untyped]) -> Hash[untyped, untyped]
15
+ def authorize_url: (?Hash[untyped, untyped]) -> String
16
+ def get_token: (*untyped) -> void
17
+ end
18
+
19
+ class Password < Base
20
+ def authorize_url: () -> void
21
+ def get_token: (String, String, ?Hash[untyped, untyped], ?Hash[Symbol, untyped]) -> OAuth2::AccessToken
22
+ end
23
+
24
+ class ClientCredentials < Base
25
+ def authorize_url: () -> void
26
+ def get_token: (?Hash[untyped, untyped], ?Hash[Symbol, untyped]) -> OAuth2::AccessToken
27
+ end
28
+
29
+ class Assertion < Base
30
+ def authorize_url: () -> void
31
+ def get_token: (Hash[untyped, untyped], Hash[Symbol, untyped], ?Hash[Symbol, untyped], ?Hash[Symbol, untyped]) -> OAuth2::AccessToken
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,5 @@
1
+ module OAuth2
2
+ module Version
3
+ VERSION: String
4
+ end
5
+ end
data/sig/oauth2.rbs ADDED
@@ -0,0 +1,9 @@
1
+ module OAuth2
2
+ OAUTH_DEBUG: bool
3
+
4
+ DEFAULT_CONFIG: untyped
5
+ @config: untyped
6
+
7
+ def self.config: () -> untyped
8
+ def self.configure: () { (untyped) -> void } -> void
9
+ end
data.tar.gz.sig ADDED
Binary file