Skip to content

Commit

Permalink
Merge pull request #449 from doanac/git-creds-improve
Browse files Browse the repository at this point in the history
Fixes to the git credential helper
  • Loading branch information
doanac authored Jan 14, 2025
2 parents d843ea6 + 8577fb2 commit ff0314f
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 43 deletions.
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func init() {
rootCmd.AddCommand(devices.NewCommand())
rootCmd.AddCommand(docker.NewCommand())
rootCmd.AddCommand(git.NewCommand())
rootCmd.AddCommand(git.NewGetCredsCommand())
rootCmd.AddCommand(events.NewCommand())
rootCmd.AddCommand(factories.NewCommand())
rootCmd.AddCommand(keys.NewCommand())
Expand Down
75 changes: 32 additions & 43 deletions subcommands/git/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"net/url"
"os"
"os/exec"
"os/user"
"path/filepath"
"runtime"
"strings"
Expand All @@ -19,15 +18,7 @@ import (

const GIT_CREDS_HELPER = "git-credential-fio"

var helperPath string

func NewCommand() *cobra.Command {
path, err := exec.LookPath("git")
if err == nil {
helperPath = filepath.Dir(path)
}
helperPath = subcommands.FindWritableDirInPath(helperPath)

cmd := &cobra.Command{
Use: "configure-git",
Short: "Configure a source.foundries.io Git credential helper",
Expand All @@ -40,12 +31,24 @@ git-credential-fio, in the same directory as the git client binary.
NOTE: The credentials will need the "source:read-update" scope to work with Git`,
Run: doGitCreds,
PreRun: func(cmd *cobra.Command, args []string) {
_, err := exec.LookPath("git")
subcommands.DieNotNil(err, "Git not found on system")
},
}
cmd.Flags().StringVarP(&helperPath, "creds-path", "", helperPath, "Path to install credential helper. This needs to be writable and in $PATH")
if len(helperPath) == 0 {
_ = cmd.MarkFlagRequired("creds-path")
return cmd
}

func NewGetCredsCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "git-credential-helper",
Hidden: true, // its used as a git-credential helper and is not user facing
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
if args[0] != "get" {
subcommands.DieNotNil(fmt.Errorf("This credential helper only supports 'get' and not '%s'", args[0]))
}
os.Exit(RunCredsHelper())
},
}
return cmd
}
Expand All @@ -66,54 +69,40 @@ func findSelf() string {
func doGitCreds(cmd *cobra.Command, args []string) {
self := findSelf()

sudoer := os.Getenv("SUDO_USER")
var execCommand string
var gitUsernameCommandArgs []string
var gitHelperCommandArgs []string

helperName := "fio"
if strings.Contains(helperPath, "~/") {
subcommands.DieNotNil(fmt.Errorf("~ character is not supported in --creds-path=. Try to run it as --creds-path %s", helperPath))
apiUrl := viper.GetString("server.url")
if len(apiUrl) == 0 {
apiUrl = "https://api.foundries.io"
}
dst := filepath.Join(helperPath, GIT_CREDS_HELPER)
parts, err := url.Parse(apiUrl)
subcommands.DieNotNil(err)
sourceUrl := strings.Replace(parts.Host, "api.", "source.", 1)

cfgFile, err := filepath.Abs(viper.GetViper().ConfigFileUsed())
subcommands.DieNotNil(err)

if runtime.GOOS == "windows" {
// To get around edge cases with git on Windows we use the absolute path
// So for example the following path will be used: C:/Program\\ Files/Git/bin/git-credential-fio.exe
dst += ".exe"
helperName = strings.ReplaceAll(filepath.ToSlash(dst), " ", "\\ ")
self = strings.ReplaceAll(filepath.ToSlash(self), " ", "\\ ")
cfgFile = strings.ReplaceAll(filepath.ToSlash(cfgFile), " ", "\\ ")
}

apiUrl := viper.GetString("server.url")
parts, err := url.Parse(apiUrl)
subcommands.DieNotNil(err)
sourceUrl := strings.Replace(parts.Host, "api.", "source.", 1)
helper := fmt.Sprintf("%s git-credential-helper -c %s", self, cfgFile)
gitUsernameCommandArgs := []string{"config", "--global", fmt.Sprintf("credential.https://%s.username", sourceUrl), "fio-oauth2"}
gitHelperCommandArgs := []string{"config", "--global", fmt.Sprintf("credential.https://%s.helper", sourceUrl), helper}

if len(sudoer) > 0 {
u, err := user.Lookup(sudoer)
subcommands.DieNotNil(err)
execCommand = "su"
gitUsernameCommandArgs = []string{u.Username, "-c", fmt.Sprintf("git config --global credential.%s.username fio-oauth2", sourceUrl)}
gitHelperCommandArgs = []string{u.Username, "-c", fmt.Sprintf("git config --global credential.https://%s.helper %s", sourceUrl, helperName)}
} else {
execCommand = "git"
gitUsernameCommandArgs = []string{"config", "--global", fmt.Sprintf("credential.https://%s.username", sourceUrl), "fio-oauth2"}
gitHelperCommandArgs = []string{"config", "--global", fmt.Sprintf("credential.https://%s.helper", sourceUrl), helperName}
}
c := exec.Command(execCommand, gitUsernameCommandArgs...)
c := exec.Command("git", gitUsernameCommandArgs...)
out, err := c.CombinedOutput()
if len(out) > 0 {
fmt.Printf("%s\n", string(out))
}
subcommands.DieNotNil(err)
c = exec.Command(execCommand, gitHelperCommandArgs...)
c = exec.Command("git", gitHelperCommandArgs...)
out, err = c.CombinedOutput()
if len(out) > 0 {
fmt.Printf("%s\n", string(out))
}
subcommands.DieNotNil(err)

fmt.Println("Symlinking", self, "to", dst)
subcommands.DieNotNil(os.Symlink(self, dst))
}

func RunCredsHelper() int {
Expand Down

0 comments on commit ff0314f

Please sign in to comment.