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.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/jamf/api/connection/token.rb', line 138 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/.
81 82 83 |
# File 'lib/jamf/api/connection/token.rb', line 81 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.
108 109 110 |
# File 'lib/jamf/api/connection/token.rb', line 108 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?.
84 85 86 |
# File 'lib/jamf/api/connection/token.rb', line 84 def creation_time @creation_time end |
#expires ⇒ Time (readonly) Also known as: expiration
91 92 93 |
# File 'lib/jamf/api/connection/token.rb', line 91 def expires @expires end |
#last_refresh ⇒ Time (readonly)
Returns when was this token last refreshed?.
88 89 90 |
# File 'lib/jamf/api/connection/token.rb', line 88 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?.
101 102 103 |
# File 'lib/jamf/api/connection/token.rb', line 101 def pw_fallback @pw_fallback end |
#ssl_options ⇒ Hash (readonly)
Returns the ssl version and verify cert, to pass into faraday connections.
73 74 75 |
# File 'lib/jamf/api/connection/token.rb', line 73 def @ssl_options end |
#ssl_version ⇒ String (readonly)
Returns the SSL version being used.
66 67 68 |
# File 'lib/jamf/api/connection/token.rb', line 66 def ssl_version @ssl_version end |
#token ⇒ String (readonly) Also known as: token_string, auth_token
Returns The token data.
76 77 78 |
# File 'lib/jamf/api/connection/token.rb', line 76 def token @token end |
#user ⇒ String (readonly)
Returns The user who generated this token.
63 64 65 |
# File 'lib/jamf/api/connection/token.rb', line 63 def user @user end |
#verify_cert ⇒ Boolean (readonly) Also known as: verify_cert?
Returns are we verifying SSL certs?.
69 70 71 |
# File 'lib/jamf/api/connection/token.rb', line 69 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
331 332 333 334 335 336 337 338 |
# File 'lib/jamf/api/connection/token.rb', line 331 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
252 253 254 255 256 |
# File 'lib/jamf/api/connection/token.rb', line 252 def expired? return unless @expires Time.now >= @expires end |
#host ⇒ Object
226 227 228 |
# File 'lib/jamf/api/connection/token.rb', line 226 def host @base_url.host end |
#init_for_api_client ⇒ Object
Initialize for an API client
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/jamf/api/connection/token.rb', line 162 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
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/jamf/api/connection/token.rb', line 188 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
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/jamf/api/connection/token.rb', line 207 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
381 382 383 384 385 |
# File 'lib/jamf/api/connection/token.rb', line 381 def invalidate @valid = !token_connection(INVALIDATE_RSRC, token: @token).post.success? @pw = nil stop_keep_alive end |
#jamf_build ⇒ String
245 246 247 248 |
# File 'lib/jamf/api/connection/token.rb', line 245 def jamf_build fetch_jamf_version unless @jamf_build @jamf_build end |
#jamf_version ⇒ Gem::Version
238 239 240 241 |
# File 'lib/jamf/api/connection/token.rb', line 238 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
322 323 324 |
# File 'lib/jamf/api/connection/token.rb', line 322 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?
261 262 263 264 265 |
# File 'lib/jamf/api/connection/token.rb', line 261 def next_refresh return unless keep_alive? @expires - @refresh_buffer end |
#port ⇒ Integer
232 233 234 |
# File 'lib/jamf/api/connection/token.rb', line 232 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.
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 |
# File 'lib/jamf/api/connection/token.rb', line 349 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
290 291 292 293 294 |
# File 'lib/jamf/api/connection/token.rb', line 290 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.
272 273 274 275 276 277 |
# File 'lib/jamf/api/connection/token.rb', line 272 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
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/jamf/api/connection/token.rb', line 398 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
423 424 425 426 427 428 |
# File 'lib/jamf/api/connection/token.rb', line 423 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”.
298 299 300 301 302 |
# File 'lib/jamf/api/connection/token.rb', line 298 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”
282 283 284 285 286 |
# File 'lib/jamf/api/connection/token.rb', line 282 def time_to_refresh return unless keep_alive? Jamf.humanize_secs secs_to_refresh end |
#valid? ⇒ Boolean
306 307 308 309 310 311 312 313 314 315 |
# File 'lib/jamf/api/connection/token.rb', line 306 def valid? @valid = if expired? false elsif !@token false else token_connection(AUTH_RSRC, token: @token).get.success? end end |