Module: DWH::Adapters::OpenAuthorizable
- Included in:
- Databricks, Snowflake
- Defined in:
- lib/dwh/adapters/open_authorizable.rb
Overview
OpenAuthorizable aka OAuth module will add functionality to get and refresh access tokens for databases that supported OAuth.
To use this module include it in your adapter and call the oauth_with class method.
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
Instance Method Summary collapse
-
#apply_oauth_tokens(access_token: nil, refresh_token: nil, expires_at: nil) ⇒ Object
You can reuse existing tokens that were saved outside of this app by passing it here.
-
#authorization_url(state: SecureRandom.hex(16), scope: nil) ⇒ Object
Generate authorization URL for user to visit.
-
#generate_oauth_tokens(authorization_code) ⇒ Object
Takes the given authorization code and generates new access and refresh tokens.
- #mint_access_token ⇒ Object
-
#oauth_access_token ⇒ String
This will return the current access_token or if it expired and refresh_token token is available it will generate a new token.
-
#oauth_authenticated? ⇒ Boolean
Check if we have a valid access token.
- #oauth_settings ⇒ Object
-
#oauth_token_info ⇒ Object
Get current state of tokens.
- #oauth_tokenization_url ⇒ Object
-
#refresh_access_token ⇒ Object
Refresh access token using refresh token.
- #validate_oauth_config ⇒ Object
Class Method Details
.included(base) ⇒ Object
42 43 44 45 46 47 48 49 |
# File 'lib/dwh/adapters/open_authorizable.rb', line 42 def self.included(base) base.extend(ClassMethods) base.include(TokenManageable) base.config :oauth_client_id, String, required: false, message: 'OAuth client_id' base.config :oauth_client_secret, String, required: false, message: 'OAuth client_secret' base.config :oauth_redirect_uri, String, required: false, message: 'OAuth redirect_uri' base.config :oauth_scope, String, required: false, message: 'OAuth scope' end |
Instance Method Details
#apply_oauth_tokens(access_token: nil, refresh_token: nil, expires_at: nil) ⇒ Object
You can reuse existing tokens that were saved outside of this app by passing it here. This could be tokens cached from a previous call to @see #generate_oauth_tokens
param access_token [String] the access token
76 77 78 79 80 |
# File 'lib/dwh/adapters/open_authorizable.rb', line 76 def apply_oauth_tokens(access_token: nil, refresh_token: nil, expires_at: nil) @oauth_access_token = access_token @oauth_refresh_token = refresh_token @token_expires_at = expires_at end |
#authorization_url(state: SecureRandom.hex(16), scope: nil) ⇒ Object
Generate authorization URL for user to visit
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/dwh/adapters/open_authorizable.rb', line 52 def (state: SecureRandom.hex(16), scope: nil) raise UnsupportedCapability, "#{adapter_name} does not support authorization-code OAuth flow" unless code_verifier = oauth_pkce_code_verifier_for_session params = { 'response_type' => 'code', 'client_id' => oauth_client_id, 'redirect_uri' => oauth_redirect_uri, 'state' => state, 'scope' => scope || oauth_scope || oauth_settings[:default_scope] }.compact params.merge!((code_verifier)) uri = URI(oauth_settings[:authorize]) uri.query = URI.encode_www_form(params) uri.to_s end |
#generate_oauth_tokens(authorization_code) ⇒ Object
Takes the given authorization code and generates new access and refresh tokens. It will also apply them.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/dwh/adapters/open_authorizable.rb', line 86 def generate_oauth_tokens() raise UnsupportedCapability, "#{adapter_name} does not support authorization-code OAuth flow" unless code_verifier = oauth_pkce_code_verifier_for_session params = { grant_type: 'authorization_code', code: , redirect_uri: oauth_redirect_uri } params.merge!(oauth_pkce_token_params(code_verifier)) response = oauth_http_client.post(oauth_tokenization_url) do |req| req.headers['Content-Type'] = 'application/x-www-form-urlencoded' req.headers['Authorization'] = basic_auth_header req.body = URI.encode_www_form(params) end oauth_token_response(response) end |
#mint_access_token ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/dwh/adapters/open_authorizable.rb', line 119 def mint_access_token raise UnsupportedCapability, "#{adapter_name} does not support client-credentials OAuth flow" unless oauth_supports_client_credentials_flow? params = oauth_client_credentials_params response = oauth_http_client.post(oauth_tokenization_url) do |req| req.headers['Content-Type'] = 'application/x-www-form-urlencoded' req.headers['Authorization'] = oauth_token_request_auth_header req.body = URI.encode_www_form(params) end oauth_token_response(response) end |
#oauth_access_token ⇒ String
This will return the current access_token or if it expired and refresh_token token is available it will generate a new token.
138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/dwh/adapters/open_authorizable.rb', line 138 def oauth_access_token load_oauth_tokens_from_store! unless @oauth_access_token || @oauth_refresh_token return @oauth_access_token if oauth_token_usable? refresh_access_token if oauth_refresh_token_usable? return @oauth_access_token if oauth_token_usable? mint_access_token if oauth_supports_client_credentials_flow? return @oauth_access_token if oauth_token_usable? raise AuthenticationError, 'Access token was never set. Either run the auth flow, mint via client credentials, or set tokens via apply_oauth_tokens.' end |
#oauth_authenticated? ⇒ Boolean
Check if we have a valid access token
153 154 155 |
# File 'lib/dwh/adapters/open_authorizable.rb', line 153 def oauth_authenticated? @oauth_access_token && oauth_token_usable? end |
#oauth_settings ⇒ Object
178 179 180 181 182 |
# File 'lib/dwh/adapters/open_authorizable.rb', line 178 def oauth_settings @oauth_settings ||= self.class.oauth_settings.transform_values do it.is_a?(Proc) ? it.call(self) : it end end |
#oauth_token_info ⇒ Object
Get current state of tokens
158 159 160 161 162 163 164 165 166 |
# File 'lib/dwh/adapters/open_authorizable.rb', line 158 def oauth_token_info { access_token: @oauth_access_token, refresh_token: @oauth_refresh_token, expires_at: @token_expires_at, expired: !oauth_token_usable?, authenticated: oauth_authenticated? } end |
#oauth_tokenization_url ⇒ Object
184 185 186 |
# File 'lib/dwh/adapters/open_authorizable.rb', line 184 def oauth_tokenization_url oauth_settings[:tokenize] end |
#refresh_access_token ⇒ Object
Refresh access token using refresh token
106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/dwh/adapters/open_authorizable.rb', line 106 def refresh_access_token raise AuthenticationError, 'No refresh token available' unless @oauth_refresh_token params = oauth_refresh_token_params response = oauth_http_client.post(oauth_tokenization_url) do |req| req.headers['Content-Type'] = 'application/x-www-form-urlencoded' req.headers['Authorization'] = oauth_token_request_auth_header req.body = URI.encode_www_form(params) end oauth_token_response(response) end |
#validate_oauth_config ⇒ Object
168 169 170 171 172 173 174 175 176 |
# File 'lib/dwh/adapters/open_authorizable.rb', line 168 def validate_oauth_config raise ConfigError, 'Missing config: oauth_client_id. Required for OAuth.' unless config[:oauth_client_id] raise ConfigError, 'Missing config: oauth_client_secret. Required for OAuth.' unless config[:oauth_client_secret] raise ConfigError, 'Missing config: oauth_redirect_uri. Required for OAuth.' if oauth_redirect_uri_required? && !config[:oauth_redirect_uri] oauth_settings if true end |