File: libgit2-helpers.jl

package info (click to toggle)
julia 1.0.3%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 49,452 kB
  • sloc: lisp: 236,453; ansic: 55,579; cpp: 25,603; makefile: 1,685; pascal: 1,130; sh: 956; asm: 86; xml: 76
file content (78 lines) | stat: -rw-r--r-- 2,873 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# This file is a part of Julia. License is MIT: https://julialang.org/license

using LibGit2: AbstractCredential, UserPasswordCredential, SSHCredential,
    CachedCredentials, CredentialPayload
using Base: something

const DEFAULT_PAYLOAD = CredentialPayload(allow_ssh_agent=false, allow_git_helpers=false)

"""
Emulates the LibGit2 credential loop to allows testing of the credential_callback function
without having to authenticate against a real server.
"""
function credential_loop(
        valid_credential::AbstractCredential,
        url::AbstractString,
        user::Union{AbstractString, Nothing},
        allowed_types::UInt32,
        payload::CredentialPayload;
        shred::Bool=true)
    cb = LibGit2.credentials_cb()
    libgitcred_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL)

    # Number of times credentials were authenticated against. With the real LibGit2
    # credential loop this would be how many times we sent credentials to the remote.
    num_authentications = 0

    # Emulate how LibGit2 uses the credential callback by repeatedly calling the function
    # until we find valid credentials or an exception is raised.
    err = Cint(0)
    while err == 0
        err = ccall(cb, Cint, (Ptr{Ptr{Cvoid}}, Cstring, Cstring, Cuint, Any),
                    libgitcred_ptr_ptr, url, something(user, C_NULL),
                    allowed_types, payload)
        num_authentications += 1

        # Check if the callback provided us with valid credentials
        if payload.credential !== nothing && payload.credential == valid_credential
            LibGit2.approve(payload, shred=shred)
            break
        end

        if num_authentications > 50
            error("Credential callback seems to be caught in an infinite loop")
        end
    end

    # Note: LibGit2.GitError(0) will not work if an error message has been set.
    git_error = if err == 0
        LibGit2.GitError(LibGit2.Error.None, LibGit2.Error.GIT_OK, "No errors")
    else
        LibGit2.GitError(err)
    end

    # Reject and shred the credential when an authentication error occurs
    if git_error.code == LibGit2.Error.EAUTH
        LibGit2.reject(payload, shred=shred)
    end

    return git_error, num_authentications, payload
end

function credential_loop(
        valid_credential::UserPasswordCredential,
        url::AbstractString,
        user::Union{AbstractString, Nothing}=nothing,
        payload::CredentialPayload=DEFAULT_PAYLOAD;
        shred::Bool=true)
    credential_loop(valid_credential, url, user, 0x000001, payload, shred=shred)
end

function credential_loop(
        valid_credential::SSHCredential,
        url::AbstractString,
        user::Union{AbstractString, Nothing}=nothing,
        payload::CredentialPayload=DEFAULT_PAYLOAD;
        shred::Bool=true)
    credential_loop(valid_credential, url, user, 0x000046, payload, shred=shred)
end