aboutsummaryrefslogtreecommitdiffstats
path: root/bridge/jira/config.go
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2020-02-15 16:01:15 +0100
committerMichael Muré <batolettre@gmail.com>2020-02-15 16:01:15 +0100
commit5c230cb81e399f12cc7a1c1688b73f549b12a5f0 (patch)
treed8795111b390d98274a644cc88dd64c7d24e598b /bridge/jira/config.go
parent0bb9ed9b0e6a53fd668be0c60127af78ddd061b5 (diff)
downloadgit-bug-5c230cb81e399f12cc7a1c1688b73f549b12a5f0.tar.gz
jira: rework to use the credential system + adapt to refactors
Diffstat (limited to 'bridge/jira/config.go')
-rw-r--r--bridge/jira/config.go166
1 files changed, 90 insertions, 76 deletions
diff --git a/bridge/jira/config.go b/bridge/jira/config.go
index 077f258a..c4743448 100644
--- a/bridge/jira/config.go
+++ b/bridge/jira/config.go
@@ -1,15 +1,13 @@
package jira
import (
- "encoding/json"
"fmt"
- "io/ioutil"
-
- "github.com/pkg/errors"
"github.com/MichaelMure/git-bug/bridge/core"
+ "github.com/MichaelMure/git-bug/bridge/core/auth"
"github.com/MichaelMure/git-bug/cache"
"github.com/MichaelMure/git-bug/input"
+ "github.com/MichaelMure/git-bug/repository"
)
const moreConfigText = `
@@ -28,32 +26,27 @@ after October 1st 2019 must use "TOKEN" authentication. You must create a user
API token and the client will provide this along with your username with each
request.`
-// Configure sets up the bridge configuration
-func (g *Jira) Configure(repo *cache.RepoCache, params core.BridgeParams) (core.Configuration, error) {
- conf := make(core.Configuration)
- conf[core.ConfigKeyTarget] = target
+func (*Jira) ValidParams() map[string]interface{} {
+ return map[string]interface{}{
+ "BaseURL": nil,
+ "Login": nil,
+ "CredPrefix": nil,
+ "Project": nil,
+ }
+}
+// Configure sets up the bridge configuration
+func (j *Jira) Configure(repo *cache.RepoCache, params core.BridgeParams) (core.Configuration, error) {
var err error
- // if params.Token != "" || params.TokenStdin {
- // return nil, fmt.Errorf(
- // "JIRA session tokens are extremely short lived. We don't store them " +
- // "in the configuration, so they are not valid for this bridge.")
- // }
-
- if params.Owner != "" {
- fmt.Println("warning: --owner is ineffective for a Jira bridge")
- }
-
- serverURL := params.URL
- if serverURL == "" {
+ baseURL := params.BaseURL
+ if baseURL == "" {
// terminal prompt
- serverURL, err = input.Prompt("JIRA server URL", "URL", input.Required)
+ baseURL, err = input.Prompt("JIRA server URL", "URL", input.Required, input.IsURL)
if err != nil {
return nil, err
}
}
- conf[keyServer] = serverURL
project := params.Project
if project == "" {
@@ -62,77 +55,56 @@ func (g *Jira) Configure(repo *cache.RepoCache, params core.BridgeParams) (core.
return nil, err
}
}
- conf[keyProject] = project
fmt.Println(credTypeText)
- credType, err := input.PromptChoice("Authentication mechanism", []string{"SESSION", "TOKEN"})
- if err != nil {
- return nil, err
- }
-
- switch credType {
- case 1:
- conf[keyCredentialsType] = "SESSION"
- case 2:
- conf[keyCredentialsType] = "TOKEN"
- }
-
- fmt.Println("How would you like to store your JIRA login credentials?")
- credTargetChoice, err := input.PromptChoice("Credential storage", []string{
- "sidecar JSON file: Your credentials will be stored in a JSON sidecar next" +
- "to your git config. Note that it will contain your JIRA password in clear" +
- "text.",
- "git-config: Your credentials will be stored in the git config. Note that" +
- "it will contain your JIRA password in clear text.",
- "username in config, askpass: Your username will be stored in the git" +
- "config. We will ask you for your password each time you execute the bridge.",
- })
- if err != nil {
- return nil, err
- }
-
- username, err := input.Prompt("JIRA username", "username", input.Required)
+ credTypeInput, err := input.PromptChoice("Authentication mechanism", []string{"SESSION", "TOKEN"})
if err != nil {
return nil, err
}
+ credType := []string{"SESSION", "TOKEN"}[credTypeInput]
- password, err := input.PromptPassword("Password", "password", input.Required)
- if err != nil {
- return nil, err
- }
+ var login string
+ var cred auth.Credential
- switch credTargetChoice {
- case 1:
- // TODO: a validator to see if the path is writable ?
- credentialsFile, err := input.Prompt("Credentials file path", "path", input.Required)
+ switch {
+ case params.CredPrefix != "":
+ cred, err = auth.LoadWithPrefix(repo, params.CredPrefix)
if err != nil {
return nil, err
}
- conf[keyCredentialsFile] = credentialsFile
- jsonData, err := json.Marshal(&SessionQuery{Username: username, Password: password})
- if err != nil {
- return nil, err
+ l, ok := cred.GetMetadata(auth.MetaKeyLogin)
+ if !ok {
+ return nil, fmt.Errorf("credential doesn't have a login")
+ }
+ login = l
+ default:
+ login := params.Login
+ if login == "" {
+ // TODO: validate username
+ login, err = input.Prompt("JIRA login", "login", input.Required)
+ if err != nil {
+ return nil, err
+ }
}
- err = ioutil.WriteFile(credentialsFile, jsonData, 0644)
+ cred, err = promptCredOptions(repo, login, baseURL)
if err != nil {
- return nil, errors.Wrap(
- err, fmt.Sprintf("Unable to write credentials to %s", credentialsFile))
+ return nil, err
}
- case 2:
- conf[keyUsername] = username
- conf[keyPassword] = password
- case 3:
- conf[keyUsername] = username
}
- err = g.ValidateConfig(conf)
+ conf := make(core.Configuration)
+ conf[core.ConfigKeyTarget] = target
+ conf[confKeyBaseUrl] = baseURL
+ conf[confKeyProject] = project
+ conf[confKeyCredentialType] = credType
+
+ err = j.ValidateConfig(conf)
if err != nil {
return nil, err
}
fmt.Printf("Attempting to login with credentials...\n")
- client := NewClient(serverURL, nil)
- err = client.Login(conf)
+ client, err := buildClient(nil, baseURL, credType, cred)
if err != nil {
return nil, err
}
@@ -144,7 +116,12 @@ func (g *Jira) Configure(repo *cache.RepoCache, params core.BridgeParams) (core.
return nil, fmt.Errorf(
"Project %s doesn't exist on %s, or authentication credentials for (%s)"+
" are invalid",
- project, serverURL, username)
+ project, baseURL, login)
+ }
+
+ err = core.FinishConfig(repo, metaKeyJiraLogin, login)
+ if err != nil {
+ return nil, err
}
fmt.Print(moreConfigText)
@@ -159,9 +136,46 @@ func (*Jira) ValidateConfig(conf core.Configuration) error {
return fmt.Errorf("unexpected target name: %v", v)
}
- if _, ok := conf[keyProject]; !ok {
- return fmt.Errorf("missing %s key", keyProject)
+ if _, ok := conf[confKeyProject]; !ok {
+ return fmt.Errorf("missing %s key", confKeyProject)
}
return nil
}
+
+func promptCredOptions(repo repository.RepoConfig, login, baseUrl string) (auth.Credential, error) {
+ creds, err := auth.List(repo,
+ auth.WithTarget(target),
+ auth.WithKind(auth.KindToken),
+ auth.WithMeta(auth.MetaKeyLogin, login),
+ auth.WithMeta(auth.MetaKeyBaseURL, baseUrl),
+ )
+ if err != nil {
+ return nil, err
+ }
+
+ cred, index, err := input.PromptCredential(target, "password", creds, []string{
+ "enter my password",
+ "ask my password each time",
+ })
+ switch {
+ case err != nil:
+ return nil, err
+ case cred != nil:
+ return cred, nil
+ case index == 0:
+ password, err := input.PromptPassword("Password", "password", input.Required)
+ if err != nil {
+ return nil, err
+ }
+ lp := auth.NewLoginPassword(target, login, password)
+ lp.SetMetadata(auth.MetaKeyLogin, login)
+ return lp, nil
+ case index == 1:
+ l := auth.NewLogin(target, login)
+ l.SetMetadata(auth.MetaKeyLogin, login)
+ return l, nil
+ default:
+ panic("missed case")
+ }
+}