aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoramine <hilalyamine@gmail.com>2019-10-24 20:16:51 +0200
committeramine <hilalyamine@gmail.com>2019-11-09 13:26:52 +0100
commitbaefa687b582632cd9cc21b945bc074c833f5389 (patch)
treeae2d8a8e918409a0db7d6949177df3660745b09d
parent3984919a3df95b8ec203bcb82b66c9c2270579c7 (diff)
downloadgit-bug-baefa687b582632cd9cc21b945bc074c833f5389.tar.gz
tokens: use a hash as token identifier instead of the token it self
-rw-r--r--bridge/core/token.go129
-rw-r--r--commands/bridge_token.go71
-rw-r--r--commands/bridge_token_add.go10
-rw-r--r--commands/bridge_token_rm.go2
-rw-r--r--doc/man/git-bug-bridge-token-add.141
-rw-r--r--doc/man/git-bug-bridge-token-rm.129
-rw-r--r--doc/man/git-bug-bridge-token.135
-rw-r--r--doc/md/git-bug_bridge.md2
-rw-r--r--doc/md/git-bug_bridge_token.md26
-rw-r--r--doc/md/git-bug_bridge_token_add.md26
-rw-r--r--doc/md/git-bug_bridge_token_rm.md22
-rw-r--r--misc/powershell_completion/git-bug10
-rw-r--r--misc/zsh_completion/git-bug6
13 files changed, 319 insertions, 90 deletions
diff --git a/bridge/core/token.go b/bridge/core/token.go
index 89c70af2..bd97cd18 100644
--- a/bridge/core/token.go
+++ b/bridge/core/token.go
@@ -1,6 +1,8 @@
package core
import (
+ "crypto/sha256"
+ "encoding/json"
"fmt"
"regexp"
"strings"
@@ -10,12 +12,14 @@ import (
const (
tokenConfigKeyPrefix = "git-bug.token"
- tokenKeyTarget = "target"
- tokenKeyScopes = "scopes"
+ tokenValueKey = "value"
+ tokenTargetKey = "target"
+ tokenScopesKey = "scopes"
)
// Token holds an API access token data
type Token struct {
+ ID string
Value string
Target string
Global bool
@@ -24,16 +28,46 @@ type Token struct {
// NewToken instantiate a new token
func NewToken(value, target string, global bool, scopes []string) *Token {
- return &Token{
+ token := &Token{
Value: value,
Target: target,
Global: global,
Scopes: scopes,
}
+
+ token.ID = hashToken(token)
+ return token
+}
+
+// Id return full token identifier. It will compute the Id if it's empty
+func (t *Token) Id() string {
+ if t.ID == "" {
+ t.ID = hashToken(t)
+ }
+
+ return t.ID
+}
+
+// HumanId return the truncated token id
+func (t *Token) HumanId() string {
+ return t.Id()[:6]
+}
+
+func hashToken(token *Token) string {
+ tokenJson, err := json.Marshal(&token)
+ if err != nil {
+ panic(err)
+ }
+
+ sum := sha256.Sum256(tokenJson)
+ return fmt.Sprintf("%x", sum)
}
// Validate ensure token important fields are valid
func (t *Token) Validate() error {
+ if t.ID == "" {
+ return fmt.Errorf("missing id")
+ }
if t.Value == "" {
return fmt.Errorf("missing value")
}
@@ -46,8 +80,17 @@ func (t *Token) Validate() error {
return nil
}
-func loadToken(repo repository.RepoConfig, value string, global bool) (*Token, error) {
- keyPrefix := fmt.Sprintf("git-bug.token.%s.", value)
+// Kind return the type of the token as string
+func (t *Token) Kind() string {
+ if t.Global {
+ return "global"
+ }
+
+ return "local"
+}
+
+func loadToken(repo repository.RepoConfig, id string, global bool) (*Token, error) {
+ keyPrefix := fmt.Sprintf("git-bug.token.%s.", id)
readerFn := repo.ReadConfigs
if global {
@@ -62,19 +105,25 @@ func loadToken(repo repository.RepoConfig, value string, global bool) (*Token, e
// trim key prefix
for key, value := range configs {
+ delete(configs, key)
newKey := strings.TrimPrefix(key, keyPrefix)
configs[newKey] = value
- delete(configs, key)
}
var ok bool
- token := &Token{Value: value, Global: global}
- token.Target, ok = configs[tokenKeyTarget]
+ token := &Token{ID: id, Global: global}
+
+ token.Value, ok = configs[tokenValueKey]
+ if !ok {
+ return nil, fmt.Errorf("empty token value")
+ }
+
+ token.Target, ok = configs[tokenTargetKey]
if !ok {
return nil, fmt.Errorf("empty token key")
}
- scopesString, ok := configs[tokenKeyScopes]
+ scopesString, ok := configs[tokenScopesKey]
if !ok {
return nil, fmt.Errorf("missing scopes config")
}
@@ -84,13 +133,13 @@ func loadToken(repo repository.RepoConfig, value string, global bool) (*Token, e
}
// GetToken loads a token from repo config
-func GetToken(repo repository.RepoConfig, value string) (*Token, error) {
- return loadToken(repo, value, false)
+func GetToken(repo repository.RepoConfig, id string) (*Token, error) {
+ return loadToken(repo, id, false)
}
// GetGlobalToken loads a token from the global config
-func GetGlobalToken(repo repository.RepoConfig, value string) (*Token, error) {
- return loadToken(repo, value, true)
+func GetGlobalToken(repo repository.RepoConfig, id string) (*Token, error) {
+ return loadToken(repo, id, true)
}
func listTokens(repo repository.RepoConfig, global bool) ([]string, error) {
@@ -131,14 +180,29 @@ func listTokens(repo repository.RepoConfig, global bool) ([]string, error) {
return result, nil
}
-// ListTokens return the list of stored tokens in the repo config
-func ListTokens(repo repository.RepoConfig) ([]string, error) {
- return listTokens(repo, false)
-}
+// ListTokens return a map representing the stored tokens in the repo config and global config
+// along with their type (global: true, local:false)
+func ListTokens(repo repository.RepoConfig) (map[string]bool, error) {
+ localTokens, err := listTokens(repo, false)
+ if err != nil {
+ return nil, err
+ }
-// ListGlobalTokens return the list of stored tokens in the global config
-func ListGlobalTokens(repo repository.RepoConfig) ([]string, error) {
- return listTokens(repo, true)
+ globalTokens, err := listTokens(repo, true)
+ if err != nil {
+ return nil, err
+ }
+
+ tokens := map[string]bool{}
+ for _, token := range localTokens {
+ tokens[token] = false
+ }
+
+ for _, token := range globalTokens {
+ tokens[token] = true
+ }
+
+ return tokens, nil
}
func storeToken(repo repository.RepoConfig, token *Token) error {
@@ -147,13 +211,19 @@ func storeToken(repo repository.RepoConfig, token *Token) error {
storeFn = repo.StoreGlobalConfig
}
- storeTargetKey := fmt.Sprintf("git-bug.token.%s.%s", token.Value, tokenKeyTarget)
- err := storeFn(storeTargetKey, token.Target)
+ storeValueKey := fmt.Sprintf("git-bug.token.%s.%s", token.Id(), tokenValueKey)
+ err := storeFn(storeValueKey, token.Value)
+ if err != nil {
+ return err
+ }
+
+ storeTargetKey := fmt.Sprintf("git-bug.token.%s.%s", token.Id(), tokenTargetKey)
+ err = storeFn(storeTargetKey, token.Target)
if err != nil {
return err
}
- storeScopesKey := fmt.Sprintf("git-bug.token.%s.%s", token.Value, tokenKeyScopes)
+ storeScopesKey := fmt.Sprintf("git-bug.token.%s.%s", token.Id(), tokenScopesKey)
return storeFn(storeScopesKey, strings.Join(token.Scopes, ","))
}
@@ -162,19 +232,14 @@ func StoreToken(repo repository.RepoConfig, token *Token) error {
return storeToken(repo, token)
}
-// StoreGlobalToken stores a token in global config
-func StoreGlobalToken(repo repository.RepoConfig, token *Token) error {
- return storeToken(repo, token)
-}
-
// RemoveToken removes a token from the repo config
-func RemoveToken(repo repository.RepoConfig, value string) error {
- keyPrefix := fmt.Sprintf("git-bug.token.%s", value)
+func RemoveToken(repo repository.RepoConfig, id string) error {
+ keyPrefix := fmt.Sprintf("git-bug.token.%s", id)
return repo.RmConfigs(keyPrefix)
}
// RemoveGlobalToken removes a token from the repo config
-func RemoveGlobalToken(repo repository.RepoConfig, value string) error {
- keyPrefix := fmt.Sprintf("git-bug.token.%s", value)
+func RemoveGlobalToken(repo repository.RepoConfig, id string) error {
+ keyPrefix := fmt.Sprintf("git-bug.token.%s", id)
return repo.RmGlobalConfigs(keyPrefix)
}
diff --git a/commands/bridge_token.go b/commands/bridge_token.go
index cb9754c3..f33ee3e3 100644
--- a/commands/bridge_token.go
+++ b/commands/bridge_token.go
@@ -14,8 +14,8 @@ import (
)
var (
- bridgeTokenLocalOnly bool
- bridgeTokenGlobalOnly bool
+ bridgeTokenLocal bool
+ bridgeTokenGlobal bool
)
func runTokenBridge(cmd *cobra.Command, args []string) error {
@@ -26,55 +26,46 @@ func runTokenBridge(cmd *cobra.Command, args []string) error {
defer backend.Close()
interrupt.RegisterCleaner(backend.Close)
- var tokens []*core.Token
- if !bridgeTokenGlobalOnly {
- localTokens, err := core.ListTokens(backend)
- if err != nil {
- return err
- }
+ tokens, err := core.ListTokens(backend)
+ if err != nil {
+ return err
+ }
- for _, id := range localTokens {
- token, err := core.GetToken(repo, id)
- if err != nil {
- return err
- }
- tokens = append(tokens, token)
+ for token, global := range tokens {
+ // TODO: filter tokens using flags
+ getTokenFn := core.GetToken
+ if global {
+ getTokenFn = core.GetGlobalToken
}
- }
- if !bridgeTokenLocalOnly {
- globalTokens, err := core.ListGlobalTokens(backend)
+ token, err := getTokenFn(repo, token)
if err != nil {
return err
}
-
- for _, id := range globalTokens {
- token, err := core.GetGlobalToken(repo, id)
- if err != nil {
- return err
- }
- tokens = append(tokens, token)
- }
+ printToken(token)
}
- for _, token := range tokens {
- valueFmt := text.LeftPadMaxLine(token.Value, 20, 0)
- targetFmt := text.LeftPadMaxLine(token.Target, 8, 0)
- scopesFmt := text.LeftPadMaxLine(strings.Join(token.Scopes, ","), 20, 0)
-
- fmt.Printf("%s %s %s %s\n",
- valueFmt,
- colors.Magenta(targetFmt),
- colors.Yellow(token.Global),
- scopesFmt,
- )
- }
return nil
}
+func printToken(token *core.Token) {
+ idFmt := text.LeftPadMaxLine(token.HumanId(), 6, 0)
+ valueFmt := text.LeftPadMaxLine(token.Value, 8, 0)
+ targetFmt := text.LeftPadMaxLine(token.Target, 8, 0)
+ scopesFmt := text.LeftPadMaxLine(strings.Join(token.Scopes, ","), 20, 0)
+
+ fmt.Printf("%s %s %s %s %s\n",
+ idFmt,
+ valueFmt,
+ colors.Magenta(targetFmt),
+ colors.Yellow(token.Kind()),
+ scopesFmt,
+ )
+}
+
var bridgeTokenCmd = &cobra.Command{
Use: "token",
- Short: "Configure and use bridge tokens.",
+ Short: "List all stored tokens.",
PreRunE: loadRepo,
RunE: runTokenBridge,
Args: cobra.NoArgs,
@@ -82,7 +73,7 @@ var bridgeTokenCmd = &cobra.Command{
func init() {
bridgeCmd.AddCommand(bridgeTokenCmd)
- bridgeTokenCmd.Flags().BoolVarP(&bridgeTokenLocalOnly, "local", "l", false, "")
- bridgeTokenCmd.Flags().BoolVarP(&bridgeTokenGlobalOnly, "global", "g", false, "")
+ bridgeTokenCmd.Flags().BoolVarP(&bridgeTokenLocal, "local", "l", false, "")
+ bridgeTokenCmd.Flags().BoolVarP(&bridgeTokenGlobal, "global", "g", false, "")
bridgeTokenCmd.Flags().SortFlags = false
}
diff --git a/commands/bridge_token_add.go b/commands/bridge_token_add.go
index 76fed237..7b7a8964 100644
--- a/commands/bridge_token_add.go
+++ b/commands/bridge_token_add.go
@@ -12,20 +12,18 @@ var (
)
func runBridgeTokenAdd(cmd *cobra.Command, args []string) error {
+ _ = bridgeToken.Id() // TODO: a better design to avoid doing this
+
if err := bridgeToken.Validate(); err != nil {
return errors.Wrap(err, "invalid token")
}
- if bridgeToken.Global {
- return core.StoreToken(repo, &bridgeToken)
- }
-
- return core.StoreGlobalToken(repo, &bridgeToken)
+ return core.StoreToken(repo, &bridgeToken)
}
var bridgeTokenAddCmd = &cobra.Command{
Use: "add",
- Short: "Configure and use bridge tokens.",
+ Short: "Create and store a new token",
PreRunE: loadRepo,
RunE: runBridgeTokenAdd,
Args: cobra.NoArgs,
diff --git a/commands/bridge_token_rm.go b/commands/bridge_token_rm.go
index 7fd79126..29fdb4f2 100644
--- a/commands/bridge_token_rm.go
+++ b/commands/bridge_token_rm.go
@@ -18,7 +18,7 @@ func runBridgeTokenRm(cmd *cobra.Command, args []string) error {
var bridgeTokenRmCmd = &cobra.Command{
Use: "rm",
- Short: "Configure and use bridge tokens.",
+ Short: "Remove token by Id.",
PreRunE: loadRepo,
RunE: runBridgeTokenRm,
Args: cobra.ExactArgs(1),
diff --git a/doc/man/git-bug-bridge-token-add.1 b/doc/man/git-bug-bridge-token-add.1
new file mode 100644
index 00000000..1eb5bb20
--- /dev/null
+++ b/doc/man/git-bug-bridge-token-add.1
@@ -0,0 +1,41 @@
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+.nh
+.ad l
+
+
+.SH NAME
+.PP
+git\-bug\-bridge\-token\-add \- Create and store a new token
+
+
+.SH SYNOPSIS
+.PP
+\fBgit\-bug bridge token add [flags]\fP
+
+
+.SH DESCRIPTION
+.PP
+Create and store a new token
+
+
+.SH OPTIONS
+.PP
+\fB\-g\fP, \fB\-\-global\fP[=false]
+
+.PP
+\fB\-v\fP, \fB\-\-value\fP=""
+
+.PP
+\fB\-t\fP, \fB\-\-target\fP=""
+
+.PP
+\fB\-s\fP, \fB\-\-scopes\fP=[]
+
+.PP
+\fB\-h\fP, \fB\-\-help\fP[=false]
+ help for add
+
+
+.SH SEE ALSO
+.PP
+\fBgit\-bug\-bridge\-token(1)\fP
diff --git a/doc/man/git-bug-bridge-token-rm.1 b/doc/man/git-bug-bridge-token-rm.1
new file mode 100644
index 00000000..5c5a16a6
--- /dev/null
+++ b/doc/man/git-bug-bridge-token-rm.1
@@ -0,0 +1,29 @@
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+.nh
+.ad l
+
+
+.SH NAME
+.PP
+git\-bug\-bridge\-token\-rm \- Remove token by Id.
+
+
+.SH SYNOPSIS
+.PP
+\fBgit\-bug bridge token rm [flags]\fP
+
+
+.SH DESCRIPTION
+.PP
+Remove token by Id.
+
+
+.SH OPTIONS
+.PP
+\fB\-h\fP, \fB\-\-help\fP[=false]
+ help for rm
+
+
+.SH SEE ALSO
+.PP
+\fBgit\-bug\-bridge\-token(1)\fP
diff --git a/doc/man/git-bug-bridge-token.1 b/doc/man/git-bug-bridge-token.1
new file mode 100644
index 00000000..d97c8e33
--- /dev/null
+++ b/doc/man/git-bug-bridge-token.1
@@ -0,0 +1,35 @@
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+.nh
+.ad l
+
+
+.SH NAME
+.PP
+git\-bug\-bridge\-token \- List all stored tokens.
+
+
+.SH SYNOPSIS
+.PP
+\fBgit\-bug bridge token [flags]\fP
+
+
+.SH DESCRIPTION
+.PP
+List all stored tokens.
+
+
+.SH OPTIONS
+.PP
+\fB\-l\fP, \fB\-\-local\fP[=false]
+
+.PP
+\fB\-g\fP, \fB\-\-global\fP[=false]
+
+.PP
+\fB\-h\fP, \fB\-\-help\fP[=false]
+ help for token
+
+
+.SH SEE ALSO
+.PP
+\fBgit\-bug\-bridge(1)\fP, \fBgit\-bug\-bridge\-token\-add(1)\fP, \fBgit\-bug\-bridge\-token\-rm(1)\fP
diff --git a/doc/md/git-bug_bridge.md b/doc/md/git-bug_bridge.md
index 7731ff4b..a965074d 100644
--- a/doc/md/git-bug_bridge.md
+++ b/doc/md/git-bug_bridge.md
@@ -23,5 +23,5 @@ git-bug bridge [flags]
* [git-bug bridge pull](git-bug_bridge_pull.md) - Pull updates.
* [git-bug bridge push](git-bug_bridge_push.md) - Push updates.
* [git-bug bridge rm](git-bug_bridge_rm.md) - Delete a configured bridge.
-* [git-bug bridge token](git-bug_bridge_token.md) - Configure and use bridge tokens.
+* [git-bug bridge token](git-bug_bridge_token.md) - List all stored tokens.
diff --git a/doc/md/git-bug_bridge_token.md b/doc/md/git-bug_bridge_token.md
new file mode 100644
index 00000000..5e6baa26
--- /dev/null
+++ b/doc/md/git-bug_bridge_token.md
@@ -0,0 +1,26 @@
+## git-bug bridge token
+
+List all stored tokens.
+
+### Synopsis
+
+List all stored tokens.
+
+```
+git-bug bridge token [flags]
+```
+
+### Options
+
+```
+ -l, --local
+ -g, --global
+ -h, --help help for token
+```
+
+### SEE ALSO
+
+* [git-bug bridge](git-bug_bridge.md) - Configure and use bridges to other bug trackers.
+* [git-bug bridge token add](git-bug_bridge_token_add.md) - Create and store a new token
+* [git-bug bridge token rm](git-bug_bridge_token_rm.md) - Remove token by Id.
+
diff --git a/doc/md/git-bug_bridge_token_add.md b/doc/md/git-bug_bridge_token_add.md
new file mode 100644
index 00000000..6ef705d0
--- /dev/null
+++ b/doc/md/git-bug_bridge_token_add.md
@@ -0,0 +1,26 @@
+## git-bug bridge token add
+
+Create and store a new token
+
+### Synopsis
+
+Create and store a new token
+
+```
+git-bug bridge token add [flags]
+```
+
+### Options
+
+```
+ -g, --global
+ -v, --value string
+ -t, --target string
+ -s, --scopes stringArray
+ -h, --help help for add
+```
+
+### SEE ALSO
+
+* [git-bug bridge token](git-bug_bridge_token.md) - List all stored tokens.
+
diff --git a/doc/md/git-bug_bridge_token_rm.md b/doc/md/git-bug_bridge_token_rm.md
new file mode 100644
index 00000000..52417a9c
--- /dev/null
+++ b/doc/md/git-bug_bridge_token_rm.md
@@ -0,0 +1,22 @@
+## git-bug bridge token rm
+
+Remove token by Id.
+
+### Synopsis
+
+Remove token by Id.
+
+```
+git-bug bridge token rm [flags]
+```
+
+### Options
+
+```
+ -h, --help help for rm
+```
+
+### SEE ALSO
+
+* [git-bug bridge token](git-bug_bridge_token.md) - List all stored tokens.
+
diff --git a/misc/powershell_completion/git-bug b/misc/powershell_completion/git-bug
index e875b8a2..d92bc04b 100644
--- a/misc/powershell_completion/git-bug
+++ b/misc/powershell_completion/git-bug
@@ -22,7 +22,6 @@ Register-ArgumentCompleter -Native -CommandName 'git-bug' -ScriptBlock {
[CompletionResult]::new('commands', 'commands', [CompletionResultType]::ParameterValue, 'Display available commands.')
[CompletionResult]::new('comment', 'comment', [CompletionResultType]::ParameterValue, 'Display or add comments to a bug.')
[CompletionResult]::new('deselect', 'deselect', [CompletionResultType]::ParameterValue, 'Clear the implicitly selected bug.')
- [CompletionResult]::new('export', 'export', [CompletionResultType]::ParameterValue, '')
[CompletionResult]::new('label', 'label', [CompletionResultType]::ParameterValue, 'Display, add or remove labels to/from a bug.')
[CompletionResult]::new('ls', 'ls', [CompletionResultType]::ParameterValue, 'List bugs.')
[CompletionResult]::new('ls-id', 'ls-id', [CompletionResultType]::ParameterValue, 'List bug identifiers.')
@@ -53,7 +52,7 @@ Register-ArgumentCompleter -Native -CommandName 'git-bug' -ScriptBlock {
[CompletionResult]::new('pull', 'pull', [CompletionResultType]::ParameterValue, 'Pull updates.')
[CompletionResult]::new('push', 'push', [CompletionResultType]::ParameterValue, 'Push updates.')
[CompletionResult]::new('rm', 'rm', [CompletionResultType]::ParameterValue, 'Delete a configured bridge.')
- [CompletionResult]::new('token', 'token', [CompletionResultType]::ParameterValue, 'Configure and use bridge tokens.')
+ [CompletionResult]::new('token', 'token', [CompletionResultType]::ParameterValue, 'List all stored tokens.')
break
}
'git-bug;bridge;configure' {
@@ -90,8 +89,8 @@ Register-ArgumentCompleter -Native -CommandName 'git-bug' -ScriptBlock {
[CompletionResult]::new('--local', 'local', [CompletionResultType]::ParameterName, '')
[CompletionResult]::new('-g', 'g', [CompletionResultType]::ParameterName, '')
[CompletionResult]::new('--global', 'global', [CompletionResultType]::ParameterName, '')
- [CompletionResult]::new('add', 'add', [CompletionResultType]::ParameterValue, 'Configure and use bridge tokens.')
- [CompletionResult]::new('rm', 'rm', [CompletionResultType]::ParameterValue, 'Configure and use bridge tokens.')
+ [CompletionResult]::new('add', 'add', [CompletionResultType]::ParameterValue, 'Create and store a new token')
+ [CompletionResult]::new('rm', 'rm', [CompletionResultType]::ParameterValue, 'Remove token by Id.')
break
}
'git-bug;bridge;token;add' {
@@ -127,9 +126,6 @@ Register-ArgumentCompleter -Native -CommandName 'git-bug' -ScriptBlock {
'git-bug;deselect' {
break
}
- 'git-bug;export' {
- break
- }
'git-bug;label' {
[CompletionResult]::new('add', 'add', [CompletionResultType]::ParameterValue, 'Add a label to a bug.')
[CompletionResult]::new('rm', 'rm', [CompletionResultType]::ParameterValue, 'Remove a label from a bug.')
diff --git a/misc/zsh_completion/git-bug b/misc/zsh_completion/git-bug
index 1f4679ad..d9da4ac2 100644
--- a/misc/zsh_completion/git-bug
+++ b/misc/zsh_completion/git-bug
@@ -118,7 +118,7 @@ function _git-bug_bridge {
"pull:Pull updates."
"push:Push updates."
"rm:Delete a configured bridge."
- "token:Configure and use bridge tokens."
+ "token:List all stored tokens."
)
_describe "command" commands
;;
@@ -181,8 +181,8 @@ function _git-bug_bridge_token {
case $state in
cmnds)
commands=(
- "add:Configure and use bridge tokens."
- "rm:Configure and use bridge tokens."
+ "add:Create and store a new token"
+ "rm:Remove token by Id."
)
_describe "command" commands
;;