Class: Jamf::Connection::Token

Inherits:
Object
  • Object
show all
Defined in:
lib/jamf/api/connection/token.rb

Overview

A token used for a JSS connection

Constant Summary collapse

JAMF_VERSION_RSRC =
'v1/jamf-pro-version'.freeze
AUTH_RSRC =
'auth'.freeze
NEW_TOKEN_RSRC =
"#{AUTH_RSRC}/tokens".freeze
KEEP_ALIVE_RSRC =
"#{AUTH_RSRC}/keepAlive".freeze
INVALIDATE_RSRC =
"#{AUTH_RSRC}/invalidateToken".freeze
AUTH_TOKEN_PFX =

this string is prepended to the token data when used for transaction authorization.

'jamf-token '.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**params) ⇒ Token

Returns a new instance of Token.



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/jamf/api/connection/token.rb', line 77

def initialize(**params)
  @valid = false
  @user = params[:user]
  @base_url = params[:base_url].is_a?(String) ? URI.parse(params[:base_url]) : params[:base_url]
  @timeout = params[:timeout] || Jamf::Connection::DFT_TIMEOUT
  @ssl_options = params[:ssl_options] || {}

  if params[:pw]
    init_from_pw params[:pw]
  elsif params[:token_string]
    init_from_token_string params[:token_string]
  else
    raise ArgumentError, 'Must provide either pw: or token_string:'
  end
end

Instance Attribute Details

#auth_tokenString (readonly)

Returns The AUTH_TOKEN_PFX with the token data, used in the Authorization header of a request.

Returns:

  • (String)

    The AUTH_TOKEN_PFX with the token data, used in the Authorization header of a request



56
57
58
# File 'lib/jamf/api/connection/token.rb', line 56

def auth_token
  @auth_token
end

#base_urlURI (readonly)

Returns The base API url, e.g. myjamf.jamfcloud.com/uapi.

Returns:



59
60
61
# File 'lib/jamf/api/connection/token.rb', line 59

def base_url
  @base_url
end

#expiresJamf::Timestamp (readonly) Also known as: expiration

Returns:



51
52
53
# File 'lib/jamf/api/connection/token.rb', line 51

def expires
  @expires
end

#last_refresh_resultSymbol? (readonly)

What happened the last time we tried to refresh?

:expired_refreshed - token was expired, a new token was created with the pw
:expired_pw_failed - token was expired, pw failed to make a new token
:expired_no_pw - token was expired, but no pw was given to make a new one
:refreshed - the token refresh worked with no need for the pw
:refresh_failed - the token refresh failed, and no pw was given to make a new one
:refreshed_with_pw - the token refresh failed, pw worked to make a new token
:refresh_failed_no_pw - the token refresh failed, pw also failed to make a new token
nil - no refresh has been attempted for this token.

Returns:

  • (Symbol, nil)

    :refreshed, :pw, :expired,:failed, or nil if never refreshed



75
76
77
# File 'lib/jamf/api/connection/token.rb', line 75

def last_refresh_result
  @last_refresh_result
end

#login_timeJamf::Timestamp (readonly)

Returns when was this token created?.

Returns:



62
63
64
# File 'lib/jamf/api/connection/token.rb', line 62

def 
  @login_time
end

#userString (readonly)

Returns The user who generated this token.

Returns:

  • (String)

    The user who generated this token



48
49
50
# File 'lib/jamf/api/connection/token.rb', line 48

def user
  @user
end

Instance Method Details

#accountObject

the Jamf::Account object assciated with this token



179
180
181
182
183
184
185
186
# File 'lib/jamf/api/connection/token.rb', line 179

def 
  return @account if @account

  resp = token_connection(AUTH_RSRC, token: @auth_token).get
  return unless resp.success?

  @account = Jamf::APIAccount.new resp.body
end

#expired?Boolean

Returns:

  • (Boolean)


146
147
148
149
150
# File 'lib/jamf/api/connection/token.rb', line 146

def expired?
  return unless @expires

  Time.now >= @expires
end

#hostString

Returns:



126
127
128
# File 'lib/jamf/api/connection/token.rb', line 126

def host
  @base_url.host
end

#init_from_pw(pw) ⇒ Object

Initialize from password



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/jamf/api/connection/token.rb', line 94

def init_from_pw(pw)
  resp = token_connection(
    NEW_TOKEN_RSRC,
    pw: pw,
    timeout: @timeout,
    ssl_opts: @ssl_options
  ).post

  if  resp.success?
    parse_token_from_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'
  end
end

#init_from_token_string(str) ⇒ Object

Initialize from token string



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/jamf/api/connection/token.rb', line 113

def init_from_token_string(str)
  str = "#{AUTH_TOKEN_PFX}#{str}" unless str.start_with? AUTH_TOKEN_PFX
  resp = token_connection(AUTH_RSRC, token: str).get
  raise Jamf::InvalidDataError, 'Token string is not valid' unless resp.success?

  @auth_token = str
  @user = resp.body.dig :account, :username

  # use this token to get a fresh one with a known expiration
  refresh
end

#invalidateObject Also known as: destroy

Make this token invalid



225
226
227
# File 'lib/jamf/api/connection/token.rb', line 225

def invalidate
  @valid = !token_connection(INVALIDATE_RSRC, token: @auth_token).post.success?
end

#jamf_buildString

Returns:



141
142
143
# File 'lib/jamf/api/connection/token.rb', line 141

def jamf_build
  raw_jamf_version.split('-').last
end

#jamf_versionString

Returns:



136
137
138
# File 'lib/jamf/api/connection/token.rb', line 136

def jamf_version
  raw_jamf_version.split('-').first
end

#portInteger

Returns:

  • (Integer)


131
132
133
# File 'lib/jamf/api/connection/token.rb', line 131

def port
  @base_url.port
end

#refresh(pw = nil) ⇒ Jamf::Timestamp 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.

Parameters:

  • pw (String) (defaults to: nil)

    Optional password to use if token refresh fails. Must be the correct passwd or the token’s user (obviously)

Returns:



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/jamf/api/connection/token.rb', line 196

def refresh(pw = nil)
  # gotta have a pw if expired
  if expired?
    # try the passwd
    return refresh_with_passwd(pw, :expired_refreshed, :expired_pw_failed) if pw

    # no passwd? no chance!
    @last_refresh_result = :expired_no_pw
    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: @auth_token).post
  if keep_alive_token_resp.success?
    parse_token_from_response keep_alive_token_resp
    @last_refresh_result = :refreshed
    return expires
  end

  # if we're here, the normal refresh failed, so try the pw
  return refresh_with_passwd(pw, :refreshed_with_pw, :refresh_failed_no_pw) if pw

  # if we're here, no pw? no chance!
  @last_refresh_result = :refresh_failed
  raise 'An error occurred while refreshing the token' unless pw
end

#secs_remainingFloat

Returns:

  • (Float)


153
154
155
156
157
# File 'lib/jamf/api/connection/token.rb', line 153

def secs_remaining
  return unless @expires

  @expires - Time.now
end

#time_remainingString

Returns e.g. “1 week 6 days 23 hours 49 minutes 56 seconds”.

Returns:

  • (String)

    e.g. “1 week 6 days 23 hours 49 minutes 56 seconds”



160
161
162
163
164
# File 'lib/jamf/api/connection/token.rb', line 160

def time_remaining
  return unless @expires

  Jamf.humanize_secs secs_remaining
end

#valid?Boolean

Returns:

  • (Boolean)


167
168
169
170
171
172
173
174
175
176
# File 'lib/jamf/api/connection/token.rb', line 167

def valid?
  @valid =
    if expired?
      false
    elsif !@auth_token
      false
    else
      token_connection(AUTH_RSRC, token: @auth_token).get.success?
    end
end