aboutsummaryrefslogtreecommitdiffstats
path: root/bridge/github
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2019-11-24 23:54:23 +0100
committerGitHub <noreply@github.com>2019-11-24 23:54:23 +0100
commit44f648a931b43d707d37cb469fead5e21a615e04 (patch)
tree356bbe10b81a1ed06ded54a5570027fda51fead6 /bridge/github
parent6345895a3d9a055927f1d4b78f254a55c1d271b6 (diff)
parent06abb5a5312dfaa1edac58cced94691e477c2ed7 (diff)
downloadgit-bug-44f648a931b43d707d37cb469fead5e21a615e04.tar.gz
Merge pull request #260 from MichaelMure/bridge
Support bridge configuration with global tokens
Diffstat (limited to 'bridge/github')
-rw-r--r--bridge/github/config.go77
-rw-r--r--bridge/github/export.go6
-rw-r--r--bridge/github/import.go4
3 files changed, 67 insertions, 20 deletions
diff --git a/bridge/github/config.go b/bridge/github/config.go
index e76a14f4..0fbbd5aa 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 = core.LoadOrCreateToken(repo, target, 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
@@ -135,8 +156,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,32 +241,58 @@ 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.LoadTokensWithTarget(repo, target)
+ if err != nil {
+ return nil, err
+ }
+
fmt.Println()
fmt.Println("[1]: user provided token")
fmt.Println("[2]: interactive token creation")
+
+ if len(tokens) > 0 {
+ fmt.Println("known tokens for Github:")
+ for i, token := range tokens {
+ if token.Target == target {
+ fmt.Printf("[%d]: %s\n", i+3, token.ID())
+ }
+ }
+ }
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(tokens)+2 {
fmt.Println("invalid input")
continue
}
- if index == 1 {
- return promptToken()
+ var token string
+ switch index {
+ case 1:
+ token, err = promptToken()
+ if err != nil {
+ return nil, err
+ }
+ case 2:
+ token, err = loginAndRequestToken(owner, project)
+ if err != nil {
+ return nil, err
+ }
+ default:
+ return tokens[index-3], nil
}
- return loginAndRequestToken(owner, project)
+ return core.LoadOrCreateToken(repo, target, token)
}
}
diff --git a/bridge/github/export.go b/bridge/github/export.go
index 2fb92636..8d515802 100644
--- a/bridge/github/export.go
+++ b/bridge/github/export.go
@@ -87,14 +87,14 @@ func (ge *githubExporter) ExportAll(ctx context.Context, repo *cache.RepoCache,
return nil, err
}
- ge.identityToken[user.Id()] = ge.conf[keyToken]
+ ge.identityToken[user.Id()] = ge.conf[core.ConfigKeyToken]
// get repository node id
ge.repositoryID, err = getRepositoryNodeID(
ctx,
ge.conf[keyOwner],
ge.conf[keyProject],
- ge.conf[keyToken],
+ ge.conf[core.ConfigKeyToken],
)
if err != nil {
@@ -512,7 +512,7 @@ func (ge *githubExporter) createGithubLabel(ctx context.Context, label, color st
req = req.WithContext(ctx)
// need the token for private repositories
- req.Header.Set("Authorization", fmt.Sprintf("token %s", ge.conf[keyToken]))
+ req.Header.Set("Authorization", fmt.Sprintf("token %s", ge.conf[core.ConfigKeyToken]))
resp, err := client.Do(req)
if err != nil {
diff --git a/bridge/github/import.go b/bridge/github/import.go
index 86444057..c0fb3d6c 100644
--- a/bridge/github/import.go
+++ b/bridge/github/import.go
@@ -39,7 +39,7 @@ func (gi *githubImporter) Init(conf core.Configuration) error {
// ImportAll iterate over all the configured repository issues and ensure the creation of the
// missing issues / timeline items / edits / label events ...
func (gi *githubImporter) ImportAll(ctx context.Context, repo *cache.RepoCache, since time.Time) (<-chan core.ImportResult, error) {
- gi.iterator = NewIterator(ctx, 10, gi.conf[keyOwner], gi.conf[keyProject], gi.conf[keyToken], since)
+ gi.iterator = NewIterator(ctx, 10, gi.conf[keyOwner], gi.conf[keyProject], gi.conf[core.ConfigKeyToken], since)
out := make(chan core.ImportResult)
gi.out = out
@@ -553,7 +553,7 @@ func (gi *githubImporter) getGhost(repo *cache.RepoCache) (*cache.IdentityCache,
"login": githubv4.String("ghost"),
}
- gc := buildClient(gi.conf[keyToken])
+ gc := buildClient(gi.conf[core.ConfigKeyToken])
ctx, cancel := context.WithTimeout(gi.iterator.ctx, defaultTimeout)
defer cancel()