diff options
Diffstat (limited to 'bridge')
-rw-r--r-- | bridge/github/config.go | 112 |
1 files changed, 98 insertions, 14 deletions
diff --git a/bridge/github/config.go b/bridge/github/config.go index e76a14f4..f24b48eb 100644 --- a/bridge/github/config.go +++ b/bridge/github/config.go @@ -21,6 +21,7 @@ import ( "golang.org/x/crypto/ssh/terminal" "github.com/MichaelMure/git-bug/bridge/core" + "github.com/MichaelMure/git-bug/entity" "github.com/MichaelMure/git-bug/repository" "github.com/MichaelMure/git-bug/util/interrupt" ) @@ -43,10 +44,12 @@ func (g *Github) Configure(repo repository.RepoCommon, params core.BridgeParams) conf := make(core.Configuration) var err error var token string + var tokenId entity.Id + var tokenObj *core.Token var owner string var project string - if (params.Token != "" || params.TokenStdin) && + if (params.Token != "" || params.TokenId != "" || params.TokenStdin) && (params.URL == "" && (params.Project == "" || params.Owner == "")) { return nil, fmt.Errorf("you must provide a project URL or Owner/Name to configure this bridge with a token") } @@ -87,11 +90,11 @@ func (g *Github) Configure(repo repository.RepoCommon, params core.BridgeParams) return nil, fmt.Errorf("invalid parameter owner: %v", owner) } - // try to get token from params if provided, else use terminal prompt to either - // enter a token or login and generate a new one + // try to get token from params if provided, else use terminal prompt + // to either enter a token or login and generate a new one, or choose + // an existing token if params.Token != "" { token = params.Token - } else if params.TokenStdin { reader := bufio.NewReader(os.Stdin) token, err = reader.ReadString('\n') @@ -99,15 +102,33 @@ func (g *Github) Configure(repo repository.RepoCommon, params core.BridgeParams) return nil, fmt.Errorf("reading from stdin: %v", err) } token = strings.TrimSuffix(token, "\n") + } else if params.TokenId != "" { + tokenId = entity.Id(params.TokenId) } else { - token, err = promptTokenOptions(owner, project) + tokenObj, err = promptTokenOptions(repo, owner, project) + if err != nil { + return nil, err + } + } + + // at this point, we check if the token already exist or we create a new one + if token != "" { + tokenObj, err = loadOrCreateToken(repo, token) if err != nil { return nil, err } + } else if tokenId != "" { + tokenObj, err = core.LoadToken(repo, entity.Id(tokenId)) + if err != nil { + return nil, err + } + if tokenObj.Target != target { + return nil, fmt.Errorf("token target is incompatible %s", tokenObj.Target) + } } // verify access to the repository with token - ok, err = validateProject(owner, project, token) + ok, err = validateProject(owner, project, tokenObj.Value) if err != nil { return nil, err } @@ -116,7 +137,7 @@ func (g *Github) Configure(repo repository.RepoCommon, params core.BridgeParams) } conf[core.ConfigKeyTarget] = target - conf[keyToken] = token + conf[core.ConfigKeyTokenId] = tokenObj.ID().String() conf[keyOwner] = owner conf[keyProject] = project @@ -128,6 +149,27 @@ func (g *Github) Configure(repo repository.RepoCommon, params core.BridgeParams) return conf, nil } +func loadOrCreateToken(repo repository.RepoCommon, tokenValue string) (*core.Token, error) { + tokens, err := core.LoadTokens(repo) + if err != nil { + return nil, err + } + + for _, token := range tokens { + if token.Target == target && token.Value == tokenValue { + return token, nil + } + } + + token := core.NewToken(tokenValue, target) + err = core.StoreToken(repo, token) + if err != nil { + return nil, err + } + + return token, nil +} + func (*Github) ValidateConfig(conf core.Configuration) error { if v, ok := conf[core.ConfigKeyTarget]; !ok { return fmt.Errorf("missing %s key", core.ConfigKeyTarget) @@ -135,8 +177,8 @@ func (*Github) ValidateConfig(conf core.Configuration) error { return fmt.Errorf("unexpected target name: %v", v) } - if _, ok := conf[keyToken]; !ok { - return fmt.Errorf("missing %s key", keyToken) + if _, ok := conf[core.ConfigKeyTokenId]; !ok { + return fmt.Errorf("missing %s key", core.ConfigKeyTokenId) } if _, ok := conf[keyOwner]; !ok { @@ -220,35 +262,77 @@ func randomFingerprint() string { return string(b) } -func promptTokenOptions(owner, project string) (string, error) { +func promptTokenOptions(repo repository.RepoCommon, owner, project string) (*core.Token, error) { for { + tokens, err := core.LoadTokens(repo) + if err != nil { + return nil, err + } + fmt.Println() fmt.Println("[1]: user provided token") fmt.Println("[2]: interactive token creation") + fmt.Println("known tokens for Github:") + + var githubTokens []*core.Token + i := 0 + for _, token := range tokens { + if token.Target == target { + fmt.Printf("[%d]: %s\n", i+3, token.ID()) + githubTokens = append(githubTokens, token) + i++ + } + } fmt.Print("Select option: ") line, err := bufio.NewReader(os.Stdin).ReadString('\n') fmt.Println() if err != nil { - return "", err + return nil, err } line = strings.TrimRight(line, "\n") index, err := strconv.Atoi(line) - if err != nil || (index != 1 && index != 2) { + if err != nil || index < 1 || index > len(githubTokens)+2 { fmt.Println("invalid input") continue } + var token string if index == 1 { - return promptToken() + token, err = promptToken() + if err != nil { + return nil, err + } + } else if index == 2 { + token, err = loginAndRequestToken(owner, project) + if err != nil { + return nil, err + } + } else { + return githubTokens[index-2], nil } - return loginAndRequestToken(owner, project) + return loadOrCreateToken(repo, token) } } +func tokenAlreadyExist(repo repository.RepoCommon, id string) (bool, error) { + tokens, err := core.LoadTokens(repo) + if err != nil { + return false, err + } + + for _, token := range tokens { + if token.Target == target && token.Value == id { + return true, nil + } + } + + return false, nil +} + func promptToken() (string, error) { fmt.Println("You can generate a new token by visiting https://github.com/settings/tokens.") fmt.Println("Choose 'Generate new token' and set the necessary access scope for your repository.") |