mirror of
https://github.com/grdl/git-get.git
synced 2026-02-04 15:39:46 +00:00
Add ssh key authentication when cloning via ssh
This commit is contained in:
@@ -16,6 +16,8 @@ const (
|
||||
DefReposRoot = "repositories"
|
||||
KeyDefaultHost = "defaultHost"
|
||||
DefDefaultHost = "github.com"
|
||||
KeyPrivateKey = "privateKey"
|
||||
DefPrivateKey = "id_rsa"
|
||||
)
|
||||
|
||||
// gitconfig provides methods for looking up configiration values inside .gitconfig file
|
||||
@@ -56,6 +58,10 @@ func setMissingValues(cfg *gitconfig) {
|
||||
if isUnsetOrEmpty(KeyDefaultHost) {
|
||||
viper.Set(KeyDefaultHost, cfg.get(KeyDefaultHost, DefDefaultHost))
|
||||
}
|
||||
|
||||
if isUnsetOrEmpty(KeyPrivateKey) {
|
||||
viper.Set(KeyPrivateKey, cfg.get(KeyPrivateKey, path.Join(home(), ".ssh", DefPrivateKey)))
|
||||
}
|
||||
}
|
||||
|
||||
// get looks up the value for a given key in gitconfig file.
|
||||
|
||||
42
pkg/repo.go
42
pkg/repo.go
@@ -3,13 +3,18 @@ package pkg
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||
go_git_ssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
|
||||
)
|
||||
|
||||
type Repo struct {
|
||||
@@ -19,25 +24,33 @@ type Repo struct {
|
||||
}
|
||||
|
||||
func CloneRepo(url *url.URL, reposRoot string, quiet bool) (*Repo, error) {
|
||||
repoSubPath := URLToPath(url)
|
||||
repoPath := path.Join(reposRoot, repoSubPath)
|
||||
repoPath := path.Join(reposRoot, URLToPath(url))
|
||||
|
||||
var output io.Writer
|
||||
var progress io.Writer
|
||||
if !quiet {
|
||||
output = os.Stdout
|
||||
progress = os.Stdout
|
||||
fmt.Printf("Cloning into '%s'...\n", repoPath)
|
||||
}
|
||||
|
||||
// TODO: can this be cleaner?
|
||||
var auth transport.AuthMethod
|
||||
var err error
|
||||
if url.Scheme == "ssh" {
|
||||
if auth, err = sshKeyAuth(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
opts := &git.CloneOptions{
|
||||
URL: url.String(),
|
||||
Auth: nil,
|
||||
Auth: auth,
|
||||
RemoteName: git.DefaultRemoteName,
|
||||
ReferenceName: "",
|
||||
SingleBranch: false,
|
||||
NoCheckout: false,
|
||||
Depth: 0,
|
||||
RecurseSubmodules: git.NoRecurseSubmodules,
|
||||
Progress: output,
|
||||
Progress: progress,
|
||||
Tags: git.AllTags,
|
||||
}
|
||||
|
||||
@@ -82,3 +95,20 @@ func (r *Repo) Fetch() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func sshKeyAuth() (transport.AuthMethod, error) {
|
||||
privateKey := viper.GetString(KeyPrivateKey)
|
||||
sshKey, err := ioutil.ReadFile(privateKey)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Failed to open ssh private key %s", privateKey)
|
||||
}
|
||||
|
||||
signer, err := ssh.ParsePrivateKey([]byte(sshKey))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Failed to parse ssh private key %s", privateKey)
|
||||
}
|
||||
|
||||
// TODO: can it ba a different user
|
||||
auth := &go_git_ssh.PublicKeys{User: "git", Signer: signer}
|
||||
return auth, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user