Skip to content

Commit

Permalink
store password_expiry_utc and oauth_refresh_token attributes
Browse files Browse the repository at this point in the history
Git 2.40 and 2.41 introduced new credential attributes https://git-scm.com/docs/git-credential#IOFMT

Signed-off-by: M Hickford <[email protected]>
  • Loading branch information
hickford committed May 27, 2023
1 parent acb9c9e commit cde309d
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 6 deletions.
44 changes: 39 additions & 5 deletions git-credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ import (
var Stdout io.Writer = os.Stdout

type gitCredentials struct {
Protocol string
Host string
Path string
Username string
Password string
Protocol string
Host string
Path string
Username string
Password string
PasswordExpiryUTC string
OAuthRefreshToken string
}

// WriteTo writes the given credentials to the given io.Writer in the git-credential format.
Expand Down Expand Up @@ -74,6 +76,22 @@ func (c *gitCredentials) WriteTo(w io.Writer) (int64, error) {
}
}

if c.PasswordExpiryUTC != "" {
i, err := io.WriteString(w, "password_expiry_utc="+c.PasswordExpiryUTC+"\n")
n += int64(i)
if err != nil {
return n, err
}
}

if c.OAuthRefreshToken != "" {
i, err := io.WriteString(w, "oauth_refresh_token="+c.OAuthRefreshToken+"\n")
n += int64(i)
if err != nil {
return n, err
}
}

return n, nil
}

Expand Down Expand Up @@ -116,6 +134,10 @@ func parseGitCredentials(r io.Reader) (*gitCredentials, error) {
c.Username = val
case "password":
c.Password = val
case "password_expiry_utc":
c.PasswordExpiryUTC = val
case "oauth_refresh_token":
c.OAuthRefreshToken = val
}
}
}
Expand Down Expand Up @@ -195,6 +217,12 @@ func (s *gc) Get(c *cli.Context) error {
// leave the username as is otherwise
cred.Username = username
}
if expiry, _ := secret.Get("password_expiry_utc"); expiry != "" {
cred.PasswordExpiryUTC = expiry
}
if rt, _ := secret.Get("oauth_refresh_token"); rt != "" {
cred.OAuthRefreshToken = rt
}

_, err = cred.WriteTo(Stdout)
if err != nil {
Expand Down Expand Up @@ -229,6 +257,12 @@ func (s *gc) Store(c *cli.Context) error {
if cred.Username != "" {
_ = secret.Set("login", cred.Username)
}
if cred.PasswordExpiryUTC != "" {
_ = secret.Set("password_expiry_utc", cred.PasswordExpiryUTC)
}
if cred.OAuthRefreshToken != "" {
_ = secret.Set("oauth_refresh_token", cred.OAuthRefreshToken)
}

if err := s.gp.Set(ctx, path, secret); err != nil {
fmt.Fprintf(os.Stderr, "gopass error: error while writing to store: %s\n", err)
Expand Down
21 changes: 20 additions & 1 deletion git-credential_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ func TestGitCredentialFormat(t *testing.T) {
"path=test\n" +
"password=secr3=t\n",
),
strings.NewReader("" +
"protocol=https\n" +
"host=example.com\n" +
"username=bob\n" +
"foo=bar\n" +
"path=test\n" +
"password=secr3=t\n" +
"password_expiry_utc=2000\n" +
"oauth_refresh_token=xyzzy\n",
),
strings.NewReader("" +
"protocol=https\n" +
"host=example.com\n" +
Expand All @@ -56,11 +66,20 @@ func TestGitCredentialFormat(t *testing.T) {
Protocol: "https",
Username: "bob",
},
{
Host: "example.com",
Password: "secr3=t",
Path: "test",
Protocol: "https",
Username: "bob",
PasswordExpiryUTC: "2000",
OAuthRefreshToken: "xyzzy",
},
{},
{},
}

expectsErr := []bool{false, true, true}
expectsErr := []bool{false, false, true, true}
for i := range data {
result, err := parseGitCredentials(data[i])
if expectsErr[i] {
Expand Down

0 comments on commit cde309d

Please sign in to comment.