Class: Aspera::OAuth::Base
- Inherits:
-
Object
- Object
- Aspera::OAuth::Base
- Defined in:
- lib/aspera/oauth/base.rb
Overview
OAuth 2 client for the REST client Generate bearer token Bearer tokens are cached in memory and in a file cache for later re-use OAuth 2.0 Authorization Framework: tools.ietf.org/html/rfc6749 Bearer Token Usage: tools.ietf.org/html/rfc6750
Direct Known Subclasses
Instance Attribute Summary collapse
-
#api ⇒ Object
readonly
The OAuth API Object.
-
#params ⇒ Object
readonly
Parameters to generate token.
-
#path_token ⇒ Object
readonly
Sub path to generate token.
Instance Method Summary collapse
-
#authorization(**kwargs) ⇒ String
Value suitable for Authorization header.
-
#base_params(add_secret: false) ⇒ Hash
Create base parameters for token creation calls.
-
#create_token_call(creation_params) ⇒ HTTPResponse
Helper method to create token as per RFC.
-
#initialize(params: {}, use_query: false, path_token: 'token', token_field: Factory::TOKEN_FIELD, cache_ids: [], **rest_params) ⇒ Base
constructor
A new instance of Base.
-
#token(cache: true, refresh: false) ⇒ Object
get an OAuth v2 token (generated, cached, refreshed) call token() to get a token.
Constructor Details
#initialize(params: {}, use_query: false, path_token: 'token', token_field: Factory::TOKEN_FIELD, cache_ids: [], **rest_params) ⇒ Base
Returns a new instance of Base.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/aspera/oauth/base.rb', line 23 def initialize( params: {}, use_query: false, path_token: 'token', token_field: Factory::TOKEN_FIELD, cache_ids: [], **rest_params ) Aspera.assert_type(params, Hash) Aspera.assert_type(cache_ids, Array) # This is the OAuth API @api = Rest.new(**rest_params) @params = params.dup.freeze @path_token = path_token @token_field = token_field @use_query = use_query # TODO: :username and :scope shall be done in class, using cache_ids @token_cache_id = Factory.cache_id(@api.base_url, self.class, cache_ids, rest_params[:username], @params[:scope]) end |
Instance Attribute Details
#api ⇒ Object (readonly)
The OAuth API Object
44 45 46 |
# File 'lib/aspera/oauth/base.rb', line 44 def api @api end |
#params ⇒ Object (readonly)
Parameters to generate token
48 49 50 |
# File 'lib/aspera/oauth/base.rb', line 48 def params @params end |
#path_token ⇒ Object (readonly)
Sub path to generate token
46 47 48 |
# File 'lib/aspera/oauth/base.rb', line 46 def path_token @path_token end |
Instance Method Details
#authorization(**kwargs) ⇒ String
Returns value suitable for Authorization header.
69 70 71 |
# File 'lib/aspera/oauth/base.rb', line 69 def (**kwargs) return OAuth::Factory.(token(**kwargs)) end |
#base_params(add_secret: false) ⇒ Hash
Create base parameters for token creation calls
62 63 64 65 66 |
# File 'lib/aspera/oauth/base.rb', line 62 def base_params(add_secret: false) call_params = @params.dup call_params.delete(:client_secret) unless add_secret return call_params end |
#create_token_call(creation_params) ⇒ HTTPResponse
Helper method to create token as per RFC
53 54 55 56 57 |
# File 'lib/aspera/oauth/base.rb', line 53 def create_token_call(creation_params) Log.log.debug{'Generating a new token'.bg_green} return @api.create(@path_token, nil, query: creation_params, ret: :resp) if @use_query return @api.create(@path_token, creation_params, content_type: Rest::MIME_WWW, ret: :resp) end |
#token(cache: true, refresh: false) ⇒ Object
get an OAuth v2 token (generated, cached, refreshed) call token() to get a token. if a token is expired (api returns 4xx), call again token(refresh: true)
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/aspera/oauth/base.rb', line 78 def token(cache: true, refresh: false) # get token info from cache (or nil), decoded with date and expiration status token_info = Factory.instance.get_token_info(@token_cache_id) if cache token_data = nil unless token_info.nil? token_data = token_info[:data] # Optional optimization: # Check if token is expired based on decoded content then force refresh if close enough # might help in case the transfer agent cannot refresh himself # `direct` agent is equipped with refresh code # an API was already called, but failed, we need to regenerate or refresh if refresh || token_info[:expired] Log.log.trace1{"refresh: #{refresh} expired: #{token_info[:expired]}"} refresh_token = nil if token_data.key?('refresh_token') && !token_data['refresh_token'].eql?('not_supported') # save possible refresh token, before deleting the cache refresh_token = token_data['refresh_token'] end # delete cache Factory.instance.persist_mgr.delete(@token_cache_id) token_data = nil # lets try the existing refresh token # NOTE: AoC admin token has no refresh, and lives by default 1800secs if !refresh_token.nil? Log.log.debug{"refresh token=[#{refresh_token}]"} begin http = create_token_call(base_params(add_secret: true).merge(grant_type: 'refresh_token', refresh_token: refresh_token)) # Save only if success json_data = http.body token_data = JSON.parse(json_data) Factory.instance.persist_mgr.put(@token_cache_id, json_data) rescue => e # Refresh token can fail. Log.log.warn{"Refresh failed: #{e}"} end end end end # no cache, nor refresh: generate a token if token_data.nil? # Call the method-specific token creation # which returns the result of create_token_call json_data = create_token.body token_data = JSON.parse(json_data) Factory.instance.persist_mgr.put(@token_cache_id, json_data) end Aspera.assert(token_data.key?(@token_field)){"API error: No such field in answer: #{@token_field}"} # ok we shall have a token here return token_data[@token_field] end |