Class: HTTPX::Plugins::OAuth::OAuthSession
- Inherits:
-
Object
- Object
- HTTPX::Plugins::OAuth::OAuthSession
- Defined in:
- lib/httpx/plugins/oauth.rb
Overview
Implements the bulk of functionality and maintains the state associated with the management of the the lifecycle of an OAuth session.
Instance Method Summary collapse
- #access_token ⇒ Object
- #expires_at ⇒ Object
-
#fetch_access_token(http) ⇒ Object
when not available, it uses the
httpobject to request new access and refresh tokens. -
#initialize(issuer:, client_id:, client_secret:, access_token: nil, refresh_token: nil, scope: nil, audience: nil, token_endpoint: nil, grant_type: nil, token_endpoint_auth_method: nil) ⇒ OAuthSession
constructor
A new instance of OAuthSession.
-
#merge(other) ⇒ Object
TODO: remove this after deprecating the ‘:oauth_session` option.
- #reset! ⇒ Object
-
#token_endpoint ⇒ Object
returns the URL where to request access and refresh tokens from.
-
#token_endpoint_auth_method ⇒ Object
returns the oauth-documented authorization method to use when requesting a token.
Constructor Details
#initialize(issuer:, client_id:, client_secret:, access_token: nil, refresh_token: nil, scope: nil, audience: nil, token_endpoint: nil, grant_type: nil, token_endpoint_auth_method: nil) ⇒ OAuthSession
Returns a new instance of OAuthSession.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/httpx/plugins/oauth.rb', line 37 def initialize( issuer:, client_id:, client_secret:, access_token: nil, refresh_token: nil, scope: nil, audience: nil, token_endpoint: nil, grant_type: nil, token_endpoint_auth_method: nil ) @issuer = URI(issuer) @client_id = client_id @client_secret = client_secret @token_endpoint = URI(token_endpoint) if token_endpoint @scope = case scope when String scope.split when Array scope end @audience = audience @access_token = access_token @refresh_token = refresh_token @token_endpoint_auth_method = String(token_endpoint_auth_method) if token_endpoint_auth_method @grant_type = grant_type || (@refresh_token ? "refresh_token" : "client_credentials") @expires_at = nil @token_mon = Monitor.new unless @token_endpoint_auth_method.nil? || SUPPORTED_AUTH_METHODS.include?(@token_endpoint_auth_method) raise Error, "#{@token_endpoint_auth_method} is not a supported auth method" end return if SUPPORTED_GRANT_TYPES.include?(@grant_type) raise Error, "#{@grant_type} is not a supported grant type" end |
Instance Method Details
#access_token ⇒ Object
90 91 92 93 94 95 96 97 98 |
# File 'lib/httpx/plugins/oauth.rb', line 90 def access_token @token_mon.synchronize do if (expires_at = @expires_at) && expires_at < Time.now.to_i reset! end @access_token end end |
#expires_at ⇒ Object
86 87 88 |
# File 'lib/httpx/plugins/oauth.rb', line 86 def expires_at @token_mon.synchronize { @expires_at } end |
#fetch_access_token(http) ⇒ Object
when not available, it uses the http object to request new access and refresh tokens.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/httpx/plugins/oauth.rb', line 107 def fetch_access_token(http) return access_token if access_token load(http) # always prefer refresh token grant if a refresh token is available grant_type = @refresh_token ? "refresh_token" : @grant_type headers = {} # : Hash[String ,String] form_post = { "grant_type" => @grant_type, "scope" => Array(@scope).join(" "), "audience" => @audience, }.compact # auth case token_endpoint_auth_method when "client_secret_post" form_post["client_id"] = @client_id form_post["client_secret"] = @client_secret when "client_secret_basic" headers["authorization"] = Authentication::Basic.new(@client_id, @client_secret).authenticate end case grant_type when "client_credentials" # do nothing when "refresh_token" ref_token = refresh_token raise Error, "cannot use the `\"refresh_token\"` grant type without a refresh token" unless ref_token form_post["refresh_token"] = ref_token end # POST /token token_request = http.build_request("POST", token_endpoint, headers: headers, form: form_post) token_request.headers.delete("authorization") unless token_endpoint_auth_method == "client_secret_basic" token_response = http.skip_auth_header { http.request(token_request) } begin token_response.raise_for_status rescue HTTPError => e @refresh_token = nil if e.response.status == 401 && (grant_type == "refresh_token") raise e end payload = token_response.json @token_mon.synchronize do @refresh_token = payload.fetch("refresh_token", @refresh_token) if (expires_in = payload["expires_in"]) @expires_at = Time.now.to_i + Integer(expires_in) end @access_token = payload["access_token"] end end |
#merge(other) ⇒ Object
TODO: remove this after deprecating the ‘:oauth_session` option
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/httpx/plugins/oauth.rb', line 168 def merge(other) obj = dup case other when OAuthSession other.instance_variables.each do |ivar| val = other.instance_variable_get(ivar) next unless val obj.instance_variable_set(ivar, val) end when Hash other.each do |k, v| obj.instance_variable_set(:"@#{k}", v) if obj.instance_variable_defined?(:"@#{k}") end end obj end |
#reset! ⇒ Object
100 101 102 103 104 |
# File 'lib/httpx/plugins/oauth.rb', line 100 def reset! @token_mon.synchronize do @access_token = @expires_at = nil end end |
#token_endpoint ⇒ Object
returns the URL where to request access and refresh tokens from.
77 78 79 |
# File 'lib/httpx/plugins/oauth.rb', line 77 def token_endpoint @token_endpoint || "#{@issuer}/token" end |
#token_endpoint_auth_method ⇒ Object
returns the oauth-documented authorization method to use when requesting a token.
82 83 84 |
# File 'lib/httpx/plugins/oauth.rb', line 82 def token_endpoint_auth_method @token_endpoint_auth_method || "client_secret_basic" end |