diff --git a/github/config.go b/github/config.go index 5d432c796c63a331978d0cd7b2476e70b348c2e3..d3397cc60b53d7e627a87f285111a8d7f6f44dc2 100644 --- a/github/config.go +++ b/github/config.go @@ -9,6 +9,7 @@ import ( "github.com/jingweno/gh/utils" "os" "path/filepath" + "regexp" ) type Config struct { @@ -40,6 +41,14 @@ func (c *Config) FetchPassword() string { return string(pass) } +func (c *Config) FetchTwoFactorCode() string { + var code string + fmt.Print("two-factor authentication code: ") + fmt.Scanln(&code) + + return code +} + func (c *Config) FetchCredentials() { var changed bool if c.User == "" { @@ -49,7 +58,16 @@ func (c *Config) FetchCredentials() { if c.Token == "" { password := c.FetchPassword() - token, err := findOrCreateToken(c.User, password) + token, err := findOrCreateToken(c.User, password, "") + // TODO: return an two factor auth failure error + if err != nil { + re := regexp.MustCompile("two-factor authentication OTP code") + if re.MatchString(fmt.Sprintf("%s", err)) { + code := c.FetchTwoFactorCode() + token, err = findOrCreateToken(c.User, password, code) + } + } + utils.Check(err) c.Token = token diff --git a/github/github.go b/github/github.go index 5b1f76dd7f9e507dd0b9d1b6d91f092f06a68510..91f3f8c4e7c520314b072c5a89165dfb8ebc5c82 100644 --- a/github/github.go +++ b/github/github.go @@ -127,9 +127,15 @@ func (gh *GitHub) repo() octokat.Repo { return octokat.Repo{Name: project.Name, UserName: project.Owner} } -func findOrCreateToken(user, password string) (string, error) { +func findOrCreateToken(user, password, twoFactorCode string) (string, error) { client := octokat.NewClient().WithLogin(user, password) - auths, err := client.Authorizations(nil) + options := &octokat.Options{} + if twoFactorCode != "" { + headers := octokat.Headers{"X-GitHub-OTP": twoFactorCode} + options.Headers = headers + } + + auths, err := client.Authorizations(options) if err != nil { return "", err } @@ -147,9 +153,9 @@ func findOrCreateToken(user, password string) (string, error) { authParam.Scopes = append(authParam.Scopes, "repo") authParam.Note = "gh" authParam.NoteURL = OAuthAppURL - options := octokat.Options{Params: authParam} + options.Params = authParam - auth, err := client.CreateAuthorization(&options) + auth, err := client.CreateAuthorization(options) if err != nil { return "", err }