Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "PkgAuthentication"
uuid = "4722fa14-9d28-45f9-a1e2-a38605bd88f0"
authors = ["Sebastian Pfitzner", "contributors"]
version = "2.2.3"
version = "2.3.0"

[deps]
Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
Expand Down
34 changes: 31 additions & 3 deletions src/PkgAuthentication.jl
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ function open_browser(url::AbstractString)
end

"""
install(server::AbstractString; maxcount = 3)
install(server::AbstractString; maxcount = 3) -> PkgAuthentication.Uninstall

Install Pkg authentication hooks for the Pkg server specified by `server`. Also
sets the `$(pkg_server_env_var_name)` environment variable to `server`.
Expand All @@ -862,7 +862,7 @@ function install(server::AbstractString; maxcount::Integer=3)
end

"""
install(; maxcount = 3)
install(; maxcount = 3) -> PkgAuthentication.Uninstall

Install Pkg authentication hooks for the Pkg server specified in the `$(pkg_server_env_var_name)`
environment variable.
Expand All @@ -872,6 +872,8 @@ must be set to the URL of a valid Pkg server.

`maxcount` determines the number of retries.

You can call the returned object (no arguments) to uninstall the Pkg authentication hooks.

!!! compat "Julia 1.4"
Pkg authentication hooks require at least Julia 1.4. On earlier versions, this
method will instead force authentication immediately.
Expand All @@ -880,8 +882,10 @@ must be set to the URL of a valid Pkg server.

```julia
julia> PkgAuthentication.install()
PkgAuthentication.Uninstall (call this object to remove Pkg hooks)

julia> PkgAuthentication.install(; maxcount = 5)
PkgAuthentication.Uninstall (call this object to remove Pkg hooks)
```
"""
function install(; maxcount::Integer=3)
Expand All @@ -891,12 +895,15 @@ function install(; maxcount::Integer=3)
_assert_pkg_server_env_var_is_set()
server = String(pkg_server())
auth_handler = generate_auth_handler(maxcount)
@static if PkgAuthentication.is_new_auth_mechanism()
uninstall_hook = @static if PkgAuthentication.is_new_auth_mechanism()
Pkg.PlatformEngines.register_auth_error_handler(server, auth_handler)
else
# old Julia versions don't support auth hooks, so let's authenticate now and be done with it
authenticate(server)
# the returned Uninstall will be a silent no-op
nothing
end
return Uninstall(uninstall_hook)
end

function generate_auth_handler(maxcount::Integer)
Expand All @@ -921,6 +928,27 @@ function generate_auth_handler(maxcount::Integer)
return auth_handler
end

"""
struct Uninstall

Wrapper around the closure returned by `Pkg.PlatformEngines.register_auth_error_handler`.
Calling this object will remove the Pkg authentication hooks.

```julia
julia> uninstall = PkgAuthentication.install()
PkgAuthentication.Uninstall (call this object to remove Pkg hooks)

julia> uninstall()
```
"""
struct Uninstall
f::Union{Base.Callable, Nothing}
end
(c::Uninstall)() = isnothing(c.f) ? nothing : c.f()
function Base.show(io::IO, ::MIME"text/plain", ::Uninstall)
print(io, "PkgAuthentication.Uninstall (call this object to remove Pkg hooks)")
end

include("precompile.jl")

end # module
19 changes: 17 additions & 2 deletions test/tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,31 @@ end
delete_token()

result = PkgAuthentication.install(test_pkg_server)
@test result isa PkgAuthentication.Uninstall
@static if PkgAuthentication.is_new_auth_mechanism()
# On Julia 1.4+, the return value of `PkgAuthentication.install` will be
# the return value from the `Pkg.PlatformEngines.register_auth_error_handler`
# call. `Pkg.PlatformEngines.register_auth_error_handler` returns a zero-arg function
# that can be called to deregister the handler.
@test result isa Function
@test result.f isa Function
else
# On Julia <1.4, the return value of `PkgAuthentication.install` will be
# the return value from the `PkgAuthentication.authenticate` call.
@test result isa PkgAuthentication.Success
@test isnothing(result.f)
end

@testset "PkgAuthentication.Uninstall" begin
let u = PkgAuthentication.Uninstall(nothing)
@test u() === nothing
end
let count = 1
u = PkgAuthentication.Uninstall(() -> (count += 1; nothing))
@test count == 1
@test u() === nothing
@test count == 2
@test u() === nothing
@test count == 3
end
end
end

Expand Down
Loading