Skip to content

Commit 408c2cf

Browse files
committed
Merge branch 'mortenpi-mp/fix-refresh'
2 parents 1b124d2 + 3669f29 commit 408c2cf

File tree

6 files changed

+41
-8
lines changed

6 files changed

+41
-8
lines changed

src/PkgAuthentication.jl

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ function authenticate(;
122122
state = initial(server)
123123
try
124124
while !(isa(state, Success) || isa(state, Failure))
125+
@debug "Calling step(::$(typeof(state)))"
125126
state = step(state)
126127
end
127128
catch err
@@ -227,20 +228,33 @@ function step(state::NeedRefresh)::Union{HasNewToken, NoAuthentication}
227228
# errors are recoverable by just getting a new token:
228229
if response isa Downloads.Response && response.status == 200
229230
try
230-
body = JSON.parse(String(take!(output)))
231-
if haskey(body, "token")
232-
return HasNewToken(state.server, body["token"])
231+
body = TOML.parse(String(take!(output)))
232+
let msg = "token refresh response"
233+
assert_dict_keys(body, "access_token", "id_token"; msg=msg)
234+
assert_dict_keys(body, "expires_in"; msg=msg)
235+
assert_dict_keys(body, "expires", "expires_at"; msg=msg)
233236
end
237+
return HasNewToken(state.server, body)
234238
catch err
235239
@debug "invalid body received while refreshing token" exception=(err, catch_backtrace())
236240
end
237241
return NoAuthentication(state.server)
238242
else
239-
@debug "request for refreshing token failed" exception=(err, catch_backtrace())
243+
@debug "request for refreshing token failed" response
240244
return NoAuthentication(state.server)
241245
end
242246
end
243247

248+
function assert_dict_keys(dict::Dict, keys...; msg::AbstractString)
249+
any(haskey(dict, key) for key in keys) && return nothing
250+
if length(keys) == 1
251+
error("Key '$(first(keys))' not present in $msg")
252+
else
253+
keys = join(string.("'", keys, "'"), ", ")
254+
error("None of $keys present in $msg")
255+
end
256+
end
257+
244258
"""
245259
Takes the token from the previous step and writes it to the auth.toml file. In order
246260
to handle potential race conditions with other writes, it will check that the write

test/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
44
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
55
PkgAuthentication = "4722fa14-9d28-45f9-a1e2-a38605bd88f0"
66
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
7+
TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
78
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
89

910
[compat]

test/authserver.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using HTTP, Random, JSON
2+
import TOML
23

34
const EXPIRY = 30
45
const CHALLENGE_EXPIRY = 10
@@ -39,7 +40,8 @@ function response_handler(req)
3940
TOKEN[] = Dict(
4041
"user_name" => "firstname lastname",
4142
"user_email" => "[email protected]",
42-
"id_token" => ID_TOKEN,
43+
"id_token" => "full-" * ID_TOKEN,
44+
"access_token" => "full-" * ID_TOKEN,
4345
"refresh_token" => refresh_token,
4446
"refresh_url" => "http://localhost:$(PORT)/auth/renew/token.toml/v2/",
4547
"expires_in" => EXPIRY,
@@ -85,10 +87,10 @@ function renew_handler(req)
8587

8688
TOKEN[]["refresh_token"] = Random.randstring(10)
8789
TOKEN[]["expires_at"] = ceil(Int, time() + EXPIRY)
90+
TOKEN[]["id_token"] = "refresh-" * ID_TOKEN
91+
TOKEN[]["access_token"] = "refresh-" * ID_TOKEN
8892

89-
return HTTP.Response(200, JSON.json(Dict(
90-
"token" => TOKEN[]
91-
)))
93+
return HTTP.Response(200, sprint(TOML.print, TOKEN[]))
9294
end
9395

9496
function check_validity(req)

test/runtests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import Pkg
77
include("util.jl")
88

99
@testset "PkgAuthentication" begin
10+
@testset "Utility functions" begin
11+
include("utilities_test.jl")
12+
end
1013
with_temp_depot() do
1114
include("tests.jl")
1215
end

test/tests.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ PkgAuthentication.register_open_browser_hook(url -> HTTP.get(url))
4545

4646
@test success isa PkgAuthentication.Success
4747
@test success.token["expires_at"] > time()
48+
@test startswith(success.token["id_token"], "full-")
4849

4950
sleeptimer = ceil(Int, success.token["expires_at"] - time() + 1)
5051
@info "sleep for $(sleeptimer)s (until refresh necessary)"
@@ -55,6 +56,7 @@ PkgAuthentication.register_open_browser_hook(url -> HTTP.get(url))
5556
@test success2 isa PkgAuthentication.Success
5657
@test success2.token["expires_at"] > time()
5758
@test success2.token["refresh_token"] !== success.token["refresh_token"]
59+
@test startswith(success2.token["id_token"], "refresh-")
5860
end
5961

6062
@testset "PkgAuthentication.install" begin

test/utilities_test.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@testset "assert_dict_keys" begin
2+
@test_throws ErrorException PkgAuthentication.assert_dict_keys(Dict(), "foo"; msg="")
3+
@test PkgAuthentication.assert_dict_keys(Dict("foo" => 0), "foo"; msg="") === nothing
4+
@test_throws ErrorException PkgAuthentication.assert_dict_keys(Dict("bar" => 0), "foo"; msg="")
5+
6+
@test PkgAuthentication.assert_dict_keys(Dict("foo" => 0, "bar" => 0), "foo", "bar"; msg="") === nothing
7+
@test PkgAuthentication.assert_dict_keys(Dict("foo" => 0), "foo", "bar"; msg="") === nothing
8+
@test PkgAuthentication.assert_dict_keys(Dict("bar" => 0), "foo", "bar"; msg="") === nothing
9+
@test_throws ErrorException PkgAuthentication.assert_dict_keys(Dict(), "foo", "bar"; msg="")
10+
@test_throws ErrorException PkgAuthentication.assert_dict_keys(Dict("baz" => 0), "foo", "bar"; msg="")
11+
end

0 commit comments

Comments
 (0)