diff options
author | Michael Muré <batolettre@gmail.com> | 2019-12-26 21:42:47 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-26 21:42:47 +0100 |
commit | 3a3a4ffacd288627f84b367e9a735c3b1451c78b (patch) | |
tree | 94ee4e247291de89abd842cd77a39dfb3919fe55 | |
parent | e96d8e6771086e20639a16abf6af30f2faa006a0 (diff) | |
parent | 864d3ed33597211f22177fce6ecb7e741db795b5 (diff) | |
download | git-bug-3a3a4ffacd288627f84b367e9a735c3b1451c78b.tar.gz |
Merge pull request #278 from MichaelMure/bridge-conf-workflow
bridge: allow to configure and pull without having set a user first
-rw-r--r-- | bridge/core/auth/credential.go | 30 | ||||
-rw-r--r-- | bridge/core/auth/token.go | 6 | ||||
-rw-r--r-- | bridge/core/bridge.go | 43 | ||||
-rw-r--r-- | bridge/github/config.go | 17 | ||||
-rw-r--r-- | bridge/github/import.go | 4 | ||||
-rw-r--r-- | bridge/github/import_test.go | 3 | ||||
-rw-r--r-- | bridge/gitlab/config.go | 17 | ||||
-rw-r--r-- | bridge/gitlab/import.go | 4 | ||||
-rw-r--r-- | bridge/gitlab/import_test.go | 3 | ||||
-rw-r--r-- | commands/bridge_auth.go | 21 | ||||
-rw-r--r-- | commands/bridge_auth_show.go | 29 | ||||
-rw-r--r-- | commands/bridge_configure.go | 2 | ||||
-rw-r--r-- | commands/bridge_pull.go | 2 | ||||
-rw-r--r-- | commands/user_adopt.go | 12 |
14 files changed, 158 insertions, 35 deletions
diff --git a/bridge/core/auth/credential.go b/bridge/core/auth/credential.go index a462a116..fd026c5d 100644 --- a/bridge/core/auth/credential.go +++ b/bridge/core/auth/credential.go @@ -32,9 +32,15 @@ func NewErrMultipleMatchCredential(matching []entity.Id) *entity.ErrMultipleMatc return entity.NewErrMultipleMatch("credential", matching) } +// Special Id to mark a credential as being associated to the default user, whoever it might be. +// The intended use is for the bridge configuration, to be able to create and store a credential +// with no identities created yet, and then select one with `git-bug user adopt` +const DefaultUserId = entity.Id("default-user") + type Credential interface { ID() entity.Id UserId() entity.Id + updateUserId(id entity.Id) Target() string Kind() CredentialKind CreateTime() time.Time @@ -42,7 +48,7 @@ type Credential interface { // Return all the specific properties of the credential that need to be saved into the configuration. // This does not include Target, User, Kind and CreateTime. - ToConfig() map[string]string + toConfig() map[string]string } // Load loads a credential from the repo config @@ -90,6 +96,7 @@ func LoadWithPrefix(repo repository.RepoConfig, prefix string) (Credential, erro return matching[0], nil } +// loadFromConfig is a helper to construct a Credential from the set of git configs func loadFromConfig(rawConfigs map[string]string, id entity.Id) (Credential, error) { keyPrefix := fmt.Sprintf("%s.%s.", configKeyPrefix, id) @@ -168,7 +175,7 @@ func PrefixExist(repo repository.RepoConfig, prefix string) bool { // Store stores a credential in the global git config func Store(repo repository.RepoConfig, cred Credential) error { - confs := cred.ToConfig() + confs := cred.toConfig() prefix := fmt.Sprintf("%s.%s.", configKeyPrefix, cred.ID()) @@ -213,6 +220,25 @@ func Remove(repo repository.RepoConfig, id entity.Id) error { return repo.GlobalConfig().RemoveAll(keyPrefix) } +// ReplaceDefaultUser update all the credential attributed to the temporary "default user" +// with a real user Id +func ReplaceDefaultUser(repo repository.RepoConfig, id entity.Id) error { + list, err := List(repo, WithUserId(DefaultUserId)) + if err != nil { + return err + } + + for _, cred := range list { + cred.updateUserId(id) + err = Store(repo, cred) + if err != nil { + return err + } + } + + return nil +} + /* * Sorting */ diff --git a/bridge/core/auth/token.go b/bridge/core/auth/token.go index 12a3bfc0..8333ef12 100644 --- a/bridge/core/auth/token.go +++ b/bridge/core/auth/token.go @@ -59,6 +59,10 @@ func (t *Token) UserId() entity.Id { return t.userId } +func (t *Token) updateUserId(id entity.Id) { + t.userId = id +} + func (t *Token) Target() string { return t.target } @@ -88,7 +92,7 @@ func (t *Token) Validate() error { return nil } -func (t *Token) ToConfig() map[string]string { +func (t *Token) toConfig() map[string]string { return map[string]string{ tokenValueKey: t.Value, } diff --git a/bridge/core/bridge.go b/bridge/core/bridge.go index c6731ff9..1d0a4681 100644 --- a/bridge/core/bridge.go +++ b/bridge/core/bridge.go @@ -43,13 +43,14 @@ type BridgeParams struct { // Bridge is a wrapper around a BridgeImpl that will bind low-level // implementation with utility code to provide high-level functions. type Bridge struct { - Name string - repo *cache.RepoCache - impl BridgeImpl - importer Importer - exporter Exporter - conf Configuration - initDone bool + Name string + repo *cache.RepoCache + impl BridgeImpl + importer Importer + exporter Exporter + conf Configuration + initImportDone bool + initExportDone bool } // Register will register a new BridgeImpl @@ -273,8 +274,25 @@ func (b *Bridge) getExporter() Exporter { return b.exporter } -func (b *Bridge) ensureInit() error { - if b.initDone { +func (b *Bridge) ensureImportInit() error { + if b.initImportDone { + return nil + } + + importer := b.getImporter() + if importer != nil { + err := importer.Init(b.repo, b.conf) + if err != nil { + return err + } + } + + b.initImportDone = true + return nil +} + +func (b *Bridge) ensureExportInit() error { + if b.initExportDone { return nil } @@ -294,8 +312,7 @@ func (b *Bridge) ensureInit() error { } } - b.initDone = true - + b.initExportDone = true return nil } @@ -313,7 +330,7 @@ func (b *Bridge) ImportAllSince(ctx context.Context, since time.Time) (<-chan Im return nil, err } - err = b.ensureInit() + err = b.ensureImportInit() if err != nil { return nil, err } @@ -367,7 +384,7 @@ func (b *Bridge) ExportAll(ctx context.Context, since time.Time) (<-chan ExportR return nil, err } - err = b.ensureInit() + err = b.ensureExportInit() if err != nil { return nil, err } diff --git a/bridge/github/config.go b/bridge/github/config.go index bc26a2fc..ea4b622f 100644 --- a/bridge/github/config.go +++ b/bridge/github/config.go @@ -25,6 +25,7 @@ import ( "github.com/MichaelMure/git-bug/bridge/core/auth" "github.com/MichaelMure/git-bug/cache" "github.com/MichaelMure/git-bug/entity" + "github.com/MichaelMure/git-bug/identity" "github.com/MichaelMure/git-bug/repository" "github.com/MichaelMure/git-bug/util/colors" "github.com/MichaelMure/git-bug/util/interrupt" @@ -89,10 +90,16 @@ func (g *Github) Configure(repo *cache.RepoCache, params core.BridgeParams) (cor } user, err := repo.GetUserIdentity() - if err != nil { + if err != nil && err != identity.ErrNoIdentitySet { return nil, err } + // default to a "to be filled" user Id if we don't have a valid one yet + userId := auth.DefaultUserId + if user != nil { + userId = user.Id() + } + var cred auth.Credential switch { @@ -101,13 +108,13 @@ func (g *Github) Configure(repo *cache.RepoCache, params core.BridgeParams) (cor if err != nil { return nil, err } - if cred.UserId() != user.Id() { + if user != nil && cred.UserId() != user.Id() { return nil, fmt.Errorf("selected credential don't match the user") } case params.TokenRaw != "": - cred = auth.NewToken(user.Id(), params.TokenRaw, target) + cred = auth.NewToken(userId, params.TokenRaw, target) default: - cred, err = promptTokenOptions(repo, user.Id(), owner, project) + cred, err = promptTokenOptions(repo, userId, owner, project) if err != nil { return nil, err } @@ -326,7 +333,7 @@ func promptToken() (string, error) { return token, nil } - fmt.Println("token is invalid") + fmt.Println("token has incorrect format") } } diff --git a/bridge/github/import.go b/bridge/github/import.go index 092e3e71..dfc851fd 100644 --- a/bridge/github/import.go +++ b/bridge/github/import.go @@ -12,6 +12,7 @@ import ( "github.com/MichaelMure/git-bug/bug" "github.com/MichaelMure/git-bug/cache" "github.com/MichaelMure/git-bug/entity" + "github.com/MichaelMure/git-bug/identity" "github.com/MichaelMure/git-bug/util/text" ) @@ -47,6 +48,9 @@ func (gi *githubImporter) Init(repo *cache.RepoCache, conf core.Configuration) e if err == nil { opts = append(opts, auth.WithUserId(user.Id())) } + if err == identity.ErrNoIdentitySet { + opts = append(opts, auth.WithUserId(auth.DefaultUserId)) + } creds, err := auth.List(repo, opts...) if err != nil { diff --git a/bridge/github/import_test.go b/bridge/github/import_test.go index 304229a0..57bab61e 100644 --- a/bridge/github/import_test.go +++ b/bridge/github/import_test.go @@ -143,6 +143,9 @@ func Test_Importer(t *testing.T) { err = author.Commit(repo) require.NoError(t, err) + err = identity.SetUserIdentity(repo, author) + require.NoError(t, err) + token := auth.NewToken(author.Id(), envToken, target) err = auth.Store(repo, token) require.NoError(t, err) diff --git a/bridge/gitlab/config.go b/bridge/gitlab/config.go index 99c27836..3a48ec4e 100644 --- a/bridge/gitlab/config.go +++ b/bridge/gitlab/config.go @@ -19,6 +19,7 @@ import ( "github.com/MichaelMure/git-bug/bridge/core/auth" "github.com/MichaelMure/git-bug/cache" "github.com/MichaelMure/git-bug/entity" + "github.com/MichaelMure/git-bug/identity" "github.com/MichaelMure/git-bug/repository" "github.com/MichaelMure/git-bug/util/colors" ) @@ -65,10 +66,16 @@ func (g *Gitlab) Configure(repo *cache.RepoCache, params core.BridgeParams) (cor } user, err := repo.GetUserIdentity() - if err != nil { + if err != nil && err != identity.ErrNoIdentitySet { return nil, err } + // default to a "to be filled" user Id if we don't have a valid one yet + userId := auth.DefaultUserId + if user != nil { + userId = user.Id() + } + var cred auth.Credential switch { @@ -77,13 +84,13 @@ func (g *Gitlab) Configure(repo *cache.RepoCache, params core.BridgeParams) (cor if err != nil { return nil, err } - if cred.UserId() != user.Id() { + if user != nil && cred.UserId() != user.Id() { return nil, fmt.Errorf("selected credential don't match the user") } case params.TokenRaw != "": - cred = auth.NewToken(user.Id(), params.TokenRaw, target) + cred = auth.NewToken(userId, params.TokenRaw, target) default: - cred, err = promptTokenOptions(repo, user.Id()) + cred, err = promptTokenOptions(repo, userId) if err != nil { return nil, err } @@ -221,7 +228,7 @@ func promptToken() (string, error) { return token, nil } - fmt.Println("token format is invalid") + fmt.Println("token has incorrect format") } } diff --git a/bridge/gitlab/import.go b/bridge/gitlab/import.go index 4fa37505..fa6bbfb6 100644 --- a/bridge/gitlab/import.go +++ b/bridge/gitlab/import.go @@ -13,6 +13,7 @@ import ( "github.com/MichaelMure/git-bug/bug" "github.com/MichaelMure/git-bug/cache" "github.com/MichaelMure/git-bug/entity" + "github.com/MichaelMure/git-bug/identity" "github.com/MichaelMure/git-bug/util/text" ) @@ -42,6 +43,9 @@ func (gi *gitlabImporter) Init(repo *cache.RepoCache, conf core.Configuration) e if err == nil { opts = append(opts, auth.WithUserId(user.Id())) } + if err == identity.ErrNoIdentitySet { + opts = append(opts, auth.WithUserId(auth.DefaultUserId)) + } creds, err := auth.List(repo, opts...) if err != nil { diff --git a/bridge/gitlab/import_test.go b/bridge/gitlab/import_test.go index 6e378b07..1e2f5d50 100644 --- a/bridge/gitlab/import_test.go +++ b/bridge/gitlab/import_test.go @@ -97,6 +97,9 @@ func TestImport(t *testing.T) { err = author.Commit(repo) require.NoError(t, err) + err = identity.SetUserIdentity(repo, author) + require.NoError(t, err) + token := auth.NewToken(author.Id(), envToken, target) err = auth.Store(repo, token) require.NoError(t, err) diff --git a/commands/bridge_auth.go b/commands/bridge_auth.go index 4e8b50c4..bfbab33c 100644 --- a/commands/bridge_auth.go +++ b/commands/bridge_auth.go @@ -37,14 +37,21 @@ func runBridgeAuth(cmd *cobra.Command, args []string) error { value = cred.Value } - user, err := backend.ResolveIdentity(cred.UserId()) - if err != nil { - return err - } - userFmt := user.DisplayName() + var userFmt string + + switch cred.UserId() { + case auth.DefaultUserId: + userFmt = colors.Red("default user") + default: + user, err := backend.ResolveIdentity(cred.UserId()) + if err != nil { + return err + } + userFmt = user.DisplayName() - if cred.UserId() == defaultUser.Id() { - userFmt = colors.Red(userFmt) + if cred.UserId() == defaultUser.Id() { + userFmt = colors.Red(userFmt) + } } fmt.Printf("%s %s %s %s %s\n", diff --git a/commands/bridge_auth_show.go b/commands/bridge_auth_show.go index 5352957d..02c56806 100644 --- a/commands/bridge_auth_show.go +++ b/commands/bridge_auth_show.go @@ -7,17 +7,46 @@ import ( "github.com/spf13/cobra" "github.com/MichaelMure/git-bug/bridge/core/auth" + "github.com/MichaelMure/git-bug/cache" + "github.com/MichaelMure/git-bug/util/colors" + "github.com/MichaelMure/git-bug/util/interrupt" ) func runBridgeAuthShow(cmd *cobra.Command, args []string) error { + backend, err := cache.NewRepoCache(repo) + if err != nil { + return err + } + defer backend.Close() + interrupt.RegisterCleaner(backend.Close) + cred, err := auth.LoadWithPrefix(repo, args[0]) if err != nil { return err } + var userFmt string + + switch cred.UserId() { + case auth.DefaultUserId: + userFmt = colors.Red("default user") + default: + user, err := backend.ResolveIdentity(cred.UserId()) + if err != nil { + return err + } + userFmt = user.DisplayName() + + defaultUser, _ := backend.GetUserIdentity() + if cred.UserId() == defaultUser.Id() { + userFmt = colors.Red(userFmt) + } + } + fmt.Printf("Id: %s\n", cred.ID()) fmt.Printf("Target: %s\n", cred.Target()) fmt.Printf("Kind: %s\n", cred.Kind()) + fmt.Printf("User: %s\n", userFmt) fmt.Printf("Creation: %s\n", cred.CreateTime().Format(time.RFC822)) switch cred := cred.(type) { diff --git a/commands/bridge_configure.go b/commands/bridge_configure.go index 26bd7bc2..0e29d06a 100644 --- a/commands/bridge_configure.go +++ b/commands/bridge_configure.go @@ -206,7 +206,7 @@ git bug bridge configure \ --target=github \ --url=https://github.com/michaelmure/git-bug \ --token=$(TOKEN)`, - PreRunE: loadRepoEnsureUser, + PreRunE: loadRepo, RunE: runBridgeConfigure, } diff --git a/commands/bridge_pull.go b/commands/bridge_pull.go index 692ec5e9..2dd3d93e 100644 --- a/commands/bridge_pull.go +++ b/commands/bridge_pull.go @@ -138,7 +138,7 @@ func parseSince(since string) (time.Time, error) { var bridgePullCmd = &cobra.Command{ Use: "pull [<name>]", Short: "Pull updates.", - PreRunE: loadRepoEnsureUser, + PreRunE: loadRepo, RunE: runBridgePull, Args: cobra.MaximumNArgs(1), } diff --git a/commands/user_adopt.go b/commands/user_adopt.go index d84d4048..a7de54d9 100644 --- a/commands/user_adopt.go +++ b/commands/user_adopt.go @@ -4,7 +4,9 @@ import ( "fmt" "os" + "github.com/MichaelMure/git-bug/bridge/core/auth" "github.com/MichaelMure/git-bug/cache" + "github.com/MichaelMure/git-bug/identity" "github.com/MichaelMure/git-bug/util/interrupt" "github.com/spf13/cobra" ) @@ -24,6 +26,16 @@ func runUserAdopt(cmd *cobra.Command, args []string) error { return err } + _, err = backend.GetUserIdentity() + if err == identity.ErrNoIdentitySet { + err = auth.ReplaceDefaultUser(repo, i.Id()) + if err != nil { + return err + } + } else if err != nil { + return err + } + err = backend.SetUserIdentity(i) if err != nil { return err |