Class: Jamf::Connection::Token
- Defined in:
- lib/jamf/api/connection/token.rb
Overview
A token used for a connection to either API
Constant Summary collapse
- AUTH_RSRC_VERSION =
'v1'.freeze
- AUTH_RSRC =
'auth'.freeze
- NEW_TOKEN_RSRC =
"#{AUTH_RSRC_VERSION}/#{AUTH_RSRC}/token".freeze
- KEEP_ALIVE_RSRC =
"#{AUTH_RSRC_VERSION}/#{AUTH_RSRC}/keep-alive".freeze
- INVALIDATE_RSRC =
"#{AUTH_RSRC_VERSION}/#{AUTH_RSRC}/invalidate-token".freeze
- JAMF_VERSION_RSRC_VERSION =
'v1'.freeze
- JAMF_VERSION_RSRC =
"#{JAMF_VERSION_RSRC_VERSION}/jamf-pro-version".freeze
- OAUTH_RSRC =
'oauth'.freeze
- API_CLIENT_TOKEN_RSRC =
"#{OAUTH_RSRC}/token".freeze
- API_CLIENT_GRANT_TYPE =
'client_credentials'.freeze
- JAMF_TRYITOUT_HOST =
Recognize the tryitout server, cuz its /auth endpoint is disabled, and it needs no tokens TODO: MOVE THIS TO THE CONNECTION CLASS
"tryitout#{Jamf::Connection::JAMFCLOUD_DOMAIN}".freeze
- JAMF_TRYITOUT_TOKEN_BODY =
{ token: 'This is a fake token, tryitout.jamfcloud.com uses internal tokens', expires: 2_000_000_000_000 }.freeze
- MIN_REFRESH_BUFFER =
Minimum seconds before expiration that the token will automatically refresh. Used as the default if :refresh is not provided in the init params
300
- REFRESH_RESULTS =
Used bu the last_refresh_result method
{ refreshed: 'Refreshed', refreshed_pw: 'Refresh failed, but new token created with cached pw', refresh_failed: 'Refresh failed, could not create new token with cached pw', refresh_failed_no_pw_fallback: 'Refresh failed, but pw_fallback was false', expired_refreshed: 'Expired, but new token created with cached pw', expired_failed: 'Expired, could not create new token with cached pw', expired_no_pw_fallback: 'Expired, but pw_fallback was false' }.freeze
Instance Attribute Summary collapse
-
#base_url ⇒ URI
readonly
The base API url, e.g.
-
#creation_http_response ⇒ Faraday::Response
readonly
The response object from instantiating a new Token object by creating a new token or validating a token string.
-
#creation_time ⇒ Time
(also: #login_time)
readonly
When was this Jamf::Connection::Token originally created?.
- #expires ⇒ Time (also: #expiration) readonly
-
#last_refresh ⇒ Time
readonly
When was this token last refreshed?.
-
#pw_fallback ⇒ Boolean
(also: #pw_fallback?)
readonly
Should the provided passwd be cached in memory, to be used to generate a new token, if a normal refresh fails?.
-
#ssl_options ⇒ Hash
readonly
The ssl version and verify cert, to pass into faraday connections.
-
#ssl_version ⇒ String
readonly
The SSL version being used.
-
#token ⇒ String
(also: #token_string, #auth_token)
readonly
The token data.
-
#user ⇒ String
readonly
The user who generated this token.
-
#verify_cert ⇒ Boolean
(also: #verify_cert?)
readonly
Are we verifying SSL certs?.
Instance Method Summary collapse
-
#account ⇒ Jamf::OAPISchemas::AuthorizationV1
the Jamf account assciated with this token, which contains info about privileges and Jamf acct group memberships and Jamf Acct settings.
- #expired? ⇒ Boolean
- #host ⇒ Object
-
#init_for_api_client ⇒ Object
Initialize for an API client.
-
#init_from_pw ⇒ Object
Initialize from password.
-
#init_from_token_string(str) ⇒ Object
Initialize from token string.
-
#initialize(**params) ⇒ Token
constructor
A new instance of Token.
-
#invalidate ⇒ Object
(also: #destroy)
Make this token invalid.
- #jamf_build ⇒ String
- #jamf_version ⇒ Gem::Version
-
#last_refresh_result ⇒ String?
What happened the last time we tried to refresh? See REFRESH_RESULTS.
-
#next_refresh ⇒ Time?
when is the next rerefresh going to happen, if we are set to keep alive?.
- #port ⇒ Integer
-
#refresh ⇒ Time
(also: #keep_alive)
Use this token to get a fresh one.
- #secs_remaining ⇒ Float
-
#secs_to_refresh ⇒ Float?
how many secs until the next refresh? will return 0 during the actual refresh process.
-
#start_keep_alive ⇒ void
creates a thread that loops forever, sleeping most of the time, but waking up every 60 seconds to see if the token is expiring in the next @refresh_buffer seconds.
-
#stop_keep_alive ⇒ void
Kills the @keep_alive_thread, if it exists, and sets.
-
#time_remaining ⇒ String
E.g.
-
#time_to_refresh ⇒ String?
Returns e.g.
- #valid? ⇒ Boolean
Constructor Details
#initialize(**params) ⇒ Token
Returns a new instance of Token.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/jamf/api/connection/token.rb', line 156 def initialize(**params) @valid = false parse_params(**params) if params[:token_string] @pw_fallback = false unless @pw init_from_token_string params[:token_string] elsif @client_id init_for_api_client elsif @user && @pw init_from_pw else raise ArgumentError, 'Must provide either user: & pw: or token:' end start_keep_alive if @keep_alive @creation_time = Time.now end |
Instance Attribute Details
#base_url ⇒ URI (readonly)
Returns The base API url, e.g. myjamf.jamfcloud.com/.
99 100 101 |
# File 'lib/jamf/api/connection/token.rb', line 99 def base_url @base_url end |
#creation_http_response ⇒ Faraday::Response (readonly)
Returns The response object from instantiating a new Token object by creating a new token or validating a token string. This is not updated when refreshing a token, only when calling Token.new.
126 127 128 |
# File 'lib/jamf/api/connection/token.rb', line 126 def creation_http_response @creation_http_response end |
#creation_time ⇒ Time (readonly) Also known as: login_time
Returns when was this Jamf::Connection::Token originally created?.
102 103 104 |
# File 'lib/jamf/api/connection/token.rb', line 102 def creation_time @creation_time end |
#expires ⇒ Time (readonly) Also known as: expiration
109 110 111 |
# File 'lib/jamf/api/connection/token.rb', line 109 def expires @expires end |
#last_refresh ⇒ Time (readonly)
Returns when was this token last refreshed?.
106 107 108 |
# File 'lib/jamf/api/connection/token.rb', line 106 def last_refresh @last_refresh end |
#pw_fallback ⇒ Boolean (readonly) Also known as: pw_fallback?
Returns Should the provided passwd be cached in memory, to be used to generate a new token, if a normal refresh fails?.
119 120 121 |
# File 'lib/jamf/api/connection/token.rb', line 119 def pw_fallback @pw_fallback end |
#ssl_options ⇒ Hash (readonly)
Returns the ssl version and verify cert, to pass into faraday connections.
91 92 93 |
# File 'lib/jamf/api/connection/token.rb', line 91 def @ssl_options end |
#ssl_version ⇒ String (readonly)
Returns the SSL version being used.
84 85 86 |
# File 'lib/jamf/api/connection/token.rb', line 84 def ssl_version @ssl_version end |
#token ⇒ String (readonly) Also known as: token_string, auth_token
Returns The token data.
94 95 96 |
# File 'lib/jamf/api/connection/token.rb', line 94 def token @token end |
#user ⇒ String (readonly)
Returns The user who generated this token.
81 82 83 |
# File 'lib/jamf/api/connection/token.rb', line 81 def user @user end |
#verify_cert ⇒ Boolean (readonly) Also known as: verify_cert?
Returns are we verifying SSL certs?.
87 88 89 |
# File 'lib/jamf/api/connection/token.rb', line 87 def verify_cert @verify_cert end |
Instance Method Details
#account ⇒ Jamf::OAPISchemas::AuthorizationV1
the Jamf account assciated with this token, which contains info about privileges and Jamf acct group memberships and Jamf Acct settings
349 350 351 352 353 354 355 356 |
# File 'lib/jamf/api/connection/token.rb', line 349 def account return @account if @account resp = token_connection(AUTH_RSRC, token: @token).get return unless resp.success? @account = Jamf::OAPISchemas::AuthorizationV1.new resp.body end |
#expired? ⇒ Boolean
270 271 272 273 274 |
# File 'lib/jamf/api/connection/token.rb', line 270 def expired? return unless @expires Time.now >= @expires end |
#host ⇒ Object
244 245 246 |
# File 'lib/jamf/api/connection/token.rb', line 244 def host @base_url.host end |
#init_for_api_client ⇒ Object
Initialize for an API client
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/jamf/api/connection/token.rb', line 180 def init_for_api_client data = { client_id: @client_id, client_secret: Base64.decode64(@pw), grant_type: API_CLIENT_GRANT_TYPE } resp = api_client_auth_connection(API_CLIENT_TOKEN_RSRC).post { |req| req.body = data } if resp.success? parse_token_from_api_client_auth resp @creation_http_response = resp whoami = token_connection(AUTH_RSRC, token: @token).get @user = "#{whoami.body[:account][:username]} (API Client)" elsif resp.status == 401 raise Jamf::AuthenticationError, 'Incorrect client_id or client_secret' else # TODO: better error reporting here raise Jamf::AuthenticationError, "An error occurred while authenticating client_id: #{resp.body}" end ensure @pw = nil end |
#init_from_pw ⇒ Object
Initialize from password
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/jamf/api/connection/token.rb', line 206 def init_from_pw resp = token_connection(NEW_TOKEN_RSRC).post if resp.success? parse_token_from_response resp @last_refresh = Time.now @creation_http_response = resp elsif resp.status == 401 raise Jamf::AuthenticationError, 'Incorrect name or password' else # TODO: better error reporting here raise Jamf::AuthenticationError, "An error occurred while authenticating: #{resp.body}" end ensure @pw = nil unless @pw_fallback end |
#init_from_token_string(str) ⇒ Object
Initialize from token string
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/jamf/api/connection/token.rb', line 225 def init_from_token_string(str) resp = token_connection(AUTH_RSRC, token: str).get raise Jamf::InvalidDataError, 'Token is not valid' unless resp.success? @creation_http_response = resp @token = str @user = resp.body.dig :account, :username # if we were given a pw for the user, and expect to use it, validate it now if @pw && @pw_fallback resp = token_connection(NEW_TOKEN_RSRC).post raise Jamf::AuthenticationError, "Incorrect password provided for token string (user: #{@user})" unless resp.success? end # use this token to get a fresh one with a known expiration refresh end |
#invalidate ⇒ Object Also known as: destroy
Make this token invalid
399 400 401 402 403 |
# File 'lib/jamf/api/connection/token.rb', line 399 def invalidate @valid = !token_connection(INVALIDATE_RSRC, token: @token).post.success? @pw = nil stop_keep_alive end |
#jamf_build ⇒ String
263 264 265 266 |
# File 'lib/jamf/api/connection/token.rb', line 263 def jamf_build fetch_jamf_version unless @jamf_build @jamf_build end |
#jamf_version ⇒ Gem::Version
256 257 258 259 |
# File 'lib/jamf/api/connection/token.rb', line 256 def jamf_version fetch_jamf_version unless @jamf_version @jamf_version end |
#last_refresh_result ⇒ String?
What happened the last time we tried to refresh? See REFRESH_RESULTS
340 341 342 |
# File 'lib/jamf/api/connection/token.rb', line 340 def last_refresh_result REFRESH_RESULTS[@last_refresh_result] end |
#next_refresh ⇒ Time?
when is the next rerefresh going to happen, if we are set to keep alive?
279 280 281 282 283 |
# File 'lib/jamf/api/connection/token.rb', line 279 def next_refresh return unless keep_alive? @expires - @refresh_buffer end |
#port ⇒ Integer
250 251 252 |
# File 'lib/jamf/api/connection/token.rb', line 250 def port @base_url.port end |
#refresh ⇒ Time Also known as: keep_alive
Use this token to get a fresh one. If a pw is provided try to use it to get a new token if a proper refresh fails.
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
# File 'lib/jamf/api/connection/token.rb', line 367 def refresh # already expired? if expired? # try the passwd if we have it return refresh_with_pw(:expired_refreshed, :expired_failed) if @pw # no passwd fallback? no chance! @last_refresh_result = :expired_no_pw_fallback raise Jamf::InvalidTokenError, 'Token has expired' end # Now try a normal refresh of our non-expired token keep_alive_token_resp = token_connection(KEEP_ALIVE_RSRC, token: @token).post if keep_alive_token_resp.success? parse_token_from_response keep_alive_token_resp @last_refresh_result = :refreshed @last_refresh = Time.now return expires end # if we're here, the normal refresh failed, so try the pw return refresh_with_pw(:refreshed_pw, :refresh_failed) if @pw # if we're here, no pw? no chance! @last_refresh_result = :refresh_failed_no_pw_fallback raise 'An error occurred while refreshing the token' end |
#secs_remaining ⇒ Float
308 309 310 311 312 |
# File 'lib/jamf/api/connection/token.rb', line 308 def secs_remaining return unless @expires @expires - Time.now end |
#secs_to_refresh ⇒ Float?
how many secs until the next refresh? will return 0 during the actual refresh process.
290 291 292 293 294 295 |
# File 'lib/jamf/api/connection/token.rb', line 290 def secs_to_refresh return unless keep_alive? secs = next_refresh - Time.now secs.negative? ? 0 : secs end |
#start_keep_alive ⇒ void
This method returns an undefined value.
creates a thread that loops forever, sleeping most of the time, but waking up every 60 seconds to see if the token is expiring in the next @refresh_buffer seconds.
If so, the token is refreshed, and we keep looping and sleeping.
Sets @keep_alive_thread to the Thread object
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 |
# File 'lib/jamf/api/connection/token.rb', line 416 def start_keep_alive return if @keep_alive_thread raise 'Token expired, cannot refresh' if expired? @keep_alive_thread = Thread.new do loop do sleep 60 begin next if secs_remaining > @refresh_buffer refresh rescue # TODO: Some kind of error reporting next end end # loop end # thread end |
#stop_keep_alive ⇒ void
This method returns an undefined value.
Kills the @keep_alive_thread, if it exists, and sets
441 442 443 444 445 446 |
# File 'lib/jamf/api/connection/token.rb', line 441 def stop_keep_alive return unless @keep_alive_thread @keep_alive_thread.kill if @keep_alive_thread.alive? @keep_alive_thread = nil end |
#time_remaining ⇒ String
Returns e.g. “1 week 6 days 23 hours 49 minutes 56 seconds”.
316 317 318 319 320 |
# File 'lib/jamf/api/connection/token.rb', line 316 def time_remaining return unless @expires JSS.humanize_secs secs_remaining end |
#time_to_refresh ⇒ String?
Returns e.g. “1 week 6 days 23 hours 49 minutes 56 seconds”
300 301 302 303 304 |
# File 'lib/jamf/api/connection/token.rb', line 300 def time_to_refresh return unless keep_alive? Jamf.humanize_secs secs_to_refresh end |
#valid? ⇒ Boolean
324 325 326 327 328 329 330 331 332 333 |
# File 'lib/jamf/api/connection/token.rb', line 324 def valid? @valid = if expired? false elsif !@token false else token_connection(AUTH_RSRC, token: @token).get.success? end end |