Skip to content

Commit 97a154b

Browse files
committed
wip
1 parent 0f8e48d commit 97a154b

File tree

1 file changed

+35
-17
lines changed

1 file changed

+35
-17
lines changed

src/PkgAuthentication.jl

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,9 @@ function step(state::NoAuthentication)::Union{RequestLogin, Failure}
186186
headers = ["Accept" => "application/json", "Content-Type" => "application/x-www-form-urlencoded"],
187187
)
188188
if response isa Downloads.Response && response.status == 200
189-
return RequestLogin(state.server, nothing, JSON.parse(String(take!(output))))
189+
body = JSON.parse(String(take!(output)))
190+
body["client_id"] = "device"
191+
return RequestLogin(state.server, "", body)
190192
end
191193

192194
challenge = Random.randstring(32)
@@ -198,7 +200,7 @@ function step(state::NoAuthentication)::Union{RequestLogin, Failure}
198200
throw = false,
199201
)
200202
if response isa Downloads.Response && response.status == 200
201-
return RequestLogin(state.server, challenge, String(take!(output)))
203+
return RequestLogin(state.server, challenge, String(take!(output)), false)
202204
else
203205
return HttpError(response)
204206
end
@@ -240,15 +242,26 @@ Base.show(io::IO, s::NeedRefresh) = print(io, "NeedRefresh($(s.server), <REDACTE
240242

241243
function step(state::NeedRefresh)::Union{HasNewToken, NoAuthentication}
242244
refresh_token = state.token["refresh_token"]
243-
headers = ["Authorization" => "Bearer $refresh_token"]
244245
output = IOBuffer()
245-
response = Downloads.request(
246-
state.token["refresh_url"],
247-
method = "GET",
248-
headers = headers,
249-
output = output,
250-
throw = false,
251-
)
246+
is_device = get(state.token, "client_id", nothing) == "device"
247+
response = if is_device
248+
Downloads.request(
249+
"$(state.server)/dex/token",
250+
method = "POST",
251+
headers = ["Content-Type" => "application/x-www-form-urlencoded"],
252+
input = IOBuffer("grant_type=refresh_token&client_id=device&refresh_token=$refresh_token"),
253+
output = output,
254+
throw = false,
255+
)
256+
else
257+
Downloads.request(
258+
state.token["refresh_url"],
259+
method = "GET",
260+
headers = ["Authorization" => "Bearer $refresh_token"],
261+
output = output,
262+
throw = false,
263+
)
264+
end
252265
# errors are recoverable by just getting a new token:
253266
if response isa Downloads.Response && response.status == 200
254267
try
@@ -258,6 +271,9 @@ function step(state::NeedRefresh)::Union{HasNewToken, NoAuthentication}
258271
assert_dict_keys(body, "expires_in"; msg=msg)
259272
assert_dict_keys(body, "expires", "expires_at"; msg=msg)
260273
end
274+
if is_device
275+
body["client_id"] = "device"
276+
end
261277
return HasNewToken(state.server, body)
262278
catch err
263279
@debug "invalid body received while refreshing token" exception=(err, catch_backtrace())
@@ -322,20 +338,21 @@ ClaimToken immediately, or to Failure if there was an unexpected failure.
322338
"""
323339
struct RequestLogin <: State
324340
server::String
325-
challenge::Union{Nothing, String}
341+
challenge::String
326342
response::Union{String, Dict{String, Any}}
327343
end
328344
Base.show(io::IO, s::RequestLogin) = print(io, "RequestLogin($(s.server), <REDACTED>, $(s.response))")
329345

330346
function step(state::RequestLogin)::Union{ClaimToken, Failure}
331-
url = if state.challenge === nothing
332-
string(state.server, "/response?", state.response)
333-
else
347+
is_device = response isa Dict{String, Any} && get(response, "client_id", nothing) == "device"
348+
url = if is_device
334349
string(state.response["verification_uri_complete"])
350+
else
351+
string(state.server, "/response?", state.response)
335352
end
336353

337354
success = open_browser(url)
338-
if success && state.challenge === nothing
355+
if success && state.is_device
339356
return ClaimToken(state.server, state.challenge, state.response, expiry=state.response["expires_in"])
340357
elseif success
341358
return ClaimToken(state.server, state.challenge, state.response)
@@ -377,7 +394,8 @@ function step(state::ClaimToken)::Union{ClaimToken, HasNewToken, Failure}
377394
sleep(state.poll_interval)
378395

379396
output = IOBuffer()
380-
if state.challenge === nothing
397+
is_device = response isa Dict{String, Any} && get(response, "client_id", nothing) == "device")
398+
if is_device
381399
response = Downloads.request(
382400
string(state.server, "/dex/token"),
383401
method = "POST",
@@ -416,7 +434,7 @@ function step(state::ClaimToken)::Union{ClaimToken, HasNewToken, Failure}
416434
end
417435
elseif response isa Downloads.Response && response.status == 200
418436
return HasNewToken(state.server, JSON.parse(String(take!(output)))["access_token"])
419-
elseif response isa Downloads.Response && response.status == 401 && state.challenge === nothing
437+
elseif response isa Downloads.Response && response.status == 401 && is_device
420438
return ClaimToken(state.server, state.challenge, state.response, state.expiry, state.start_time, state.timeout, state.poll_interval, state.failures + 1, state.max_failures)
421439
else
422440
return HttpError(response)

0 commit comments

Comments
 (0)