mirror of
https://github.com/grdl/git-get.git
synced 2026-02-05 04:24:41 +00:00
Add ssh credentials callback when cloning via ssh protocol
This commit is contained in:
38
pkg/repo.go
38
pkg/repo.go
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
git "github.com/libgit2/git2go/v30"
|
||||
@@ -15,6 +16,28 @@ type Repo struct {
|
||||
Status *RepoStatus
|
||||
}
|
||||
|
||||
func credentialsCallback(url string, username string, allowedTypes git.CredType) (*git.Cred, error) {
|
||||
home, err := homedir.Dir()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed getting user home directory")
|
||||
}
|
||||
|
||||
// TODO: Add option to provide custom path
|
||||
publicKey := path.Join(home, ".ssh", "id_rsa.pub")
|
||||
privateKey := path.Join(home, ".ssh", "id_rsa")
|
||||
|
||||
cred, err := git.NewCredSshKey(username, publicKey, privateKey, "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed getting SSH credentials")
|
||||
}
|
||||
return cred, err
|
||||
}
|
||||
|
||||
func certificateCheckCallback(cert *git.Certificate, valid bool, hostname string) git.ErrorCode {
|
||||
// TODO: check the certificate
|
||||
return 0
|
||||
}
|
||||
|
||||
func CloneRepo(url *urlpkg.URL, repoRoot string) (path string, err error) {
|
||||
repoPath := URLToPath(url)
|
||||
|
||||
@@ -24,15 +47,20 @@ func CloneRepo(url *urlpkg.URL, repoRoot string) (path string, err error) {
|
||||
}
|
||||
|
||||
options := &git.CloneOptions{
|
||||
CheckoutOpts: nil,
|
||||
FetchOptions: nil,
|
||||
Bare: false,
|
||||
CheckoutBranch: "",
|
||||
RemoteCreateCallback: nil,
|
||||
Bare: false,
|
||||
CheckoutBranch: "",
|
||||
FetchOptions: &git.FetchOptions{
|
||||
RemoteCallbacks: git.RemoteCallbacks{
|
||||
CredentialsCallback: credentialsCallback,
|
||||
CertificateCheckCallback: certificateCheckCallback,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err = git.Clone(url.String(), path, options)
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(path)
|
||||
|
||||
return path, errors.Wrap(err, "Failed cloning repo")
|
||||
}
|
||||
return path, nil
|
||||
|
||||
22
pkg/url.go
22
pkg/url.go
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// scpSyntax matches the SCP-like addresses used by the ssh procotol (eg, [user@]host.xz:path/to/repo.git/).
|
||||
// scpSyntax matches the SCP-like addresses used by the ssh protocol (eg, [user@]host.xz:path/to/repo.git/).
|
||||
// See: https://golang.org/src/cmd/go/internal/get/vcs.go
|
||||
var scpSyntax = regexp.MustCompile(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`)
|
||||
|
||||
@@ -34,22 +34,34 @@ func ParseURL(rawURL string) (url *urlpkg.URL, err error) {
|
||||
return nil, errors.New("Parsed URL is empty")
|
||||
}
|
||||
|
||||
if url.Scheme == "" || url.Scheme == "git+ssh" {
|
||||
if url.Scheme == "git+ssh" {
|
||||
url.Scheme = "ssh"
|
||||
}
|
||||
|
||||
// Default to "git" user when using ssh and no user is provided
|
||||
if url.Scheme == "ssh" && url.User == nil {
|
||||
url.User = urlpkg.User("git")
|
||||
}
|
||||
|
||||
// Default to https
|
||||
if url.Scheme == "" {
|
||||
url.Scheme = "https"
|
||||
}
|
||||
|
||||
// TODO: Default to github host
|
||||
|
||||
return url, nil
|
||||
}
|
||||
|
||||
func URLToPath(url *urlpkg.URL) (repoPath string) {
|
||||
// remove port numbers from host
|
||||
// Remove port numbers from host
|
||||
repoHost := strings.Split(url.Host, ":")[0]
|
||||
|
||||
// remove trailing ".git" from repo name
|
||||
// Remove trailing ".git" from repo name
|
||||
repoPath = path.Join(repoHost, url.Path)
|
||||
repoPath = strings.TrimSuffix(repoPath, ".git")
|
||||
|
||||
// remove tilde (~) char from username
|
||||
// Remove tilde (~) char from username
|
||||
repoPath = strings.ReplaceAll(repoPath, "~", "")
|
||||
|
||||
return repoPath
|
||||
|
||||
Reference in New Issue
Block a user