diff options
-rw-r--r-- | bridge/core/token.go | 168 | ||||
-rw-r--r-- | commands/bridge_token.go | 29 | ||||
-rw-r--r-- | commands/bridge_token_add.go | 16 | ||||
-rw-r--r-- | commands/bridge_token_rm.go | 8 |
4 files changed, 64 insertions, 157 deletions
diff --git a/bridge/core/token.go b/bridge/core/token.go index cd5303d5..09294e49 100644 --- a/bridge/core/token.go +++ b/bridge/core/token.go @@ -2,11 +2,14 @@ package core import ( "crypto/sha256" - "encoding/json" "fmt" - "github.com/MichaelMure/git-bug/entity" "regexp" + "strconv" "strings" + "time" + + "github.com/MichaelMure/git-bug/entity" + "github.com/araddon/dateparse" "github.com/MichaelMure/git-bug/repository" ) @@ -15,58 +18,37 @@ const ( tokenConfigKeyPrefix = "git-bug.token" tokenValueKey = "value" tokenTargetKey = "target" - tokenScopesKey = "scopes" + tokenCreateTimeKey = "createtime" ) // Token holds an API access token data type Token struct { - id entity.Id - Value string - Target string - Global bool - Scopes []string + ID entity.Id + Value string + Target string + CreateTime time.Time } // NewToken instantiate a new token -func NewToken(value, target string, global bool, scopes []string) *Token { +func NewToken(value, target string) *Token { token := &Token{ - Value: value, - Target: target, - Global: global, - Scopes: scopes, + Value: value, + Target: target, + CreateTime: time.Now(), } - token.id = entity.Id(hashToken(token)) + token.ID = entity.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 = entity.Id(hashToken(t)) - } - - return t.id.String() -} - -// HumanId return the truncated token id -func (t *Token) HumanId() string { - return t.id.Human() -} - func hashToken(token *Token) string { - tokenJson, err := json.Marshal(&token) - if err != nil { - panic(err) - } - - sum := sha256.Sum256(tokenJson) + sum := sha256.Sum256([]byte(token.Value)) return fmt.Sprintf("%x", sum) } // Validate ensure token important fields are valid func (t *Token) Validate() error { - if t.id == "" { + if t.ID == "" { return fmt.Errorf("missing id") } if t.Value == "" { @@ -75,31 +57,21 @@ func (t *Token) Validate() error { if t.Target == "" { return fmt.Errorf("missing target") } + if t.CreateTime.Equal(time.Time{}) { + return fmt.Errorf("missing creation time") + } if _, ok := bridgeImpl[t.Target]; !ok { return fmt.Errorf("unknown target") } return nil } -// 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) { +// LoadToken loads a token from repo config +func LoadToken(repo repository.RepoCommon, id string) (*Token, error) { keyPrefix := fmt.Sprintf("git-bug.token.%s.", id) - readerFn := repo.ReadConfigs - if global { - readerFn = repo.ReadGlobalConfigs - } - // read token config pairs - configs, err := readerFn(keyPrefix) + configs, err := repo.GlobalConfig().ReadAll(keyPrefix) if err != nil { return nil, err } @@ -111,9 +83,9 @@ func loadToken(repo repository.RepoConfig, id string, global bool) (*Token, erro configs[newKey] = value } - var ok bool - token := &Token{id: entity.Id(id), Global: global} + token := &Token{ID: entity.Id(id)} + var ok bool token.Value, ok = configs[tokenValueKey] if !ok { return nil, fmt.Errorf("empty token value") @@ -124,32 +96,22 @@ func loadToken(repo repository.RepoConfig, id string, global bool) (*Token, erro return nil, fmt.Errorf("empty token key") } - scopesString, ok := configs[tokenScopesKey] + createTime, ok := configs[tokenCreateTimeKey] if !ok { - return nil, fmt.Errorf("missing scopes config") + return nil, fmt.Errorf("missing createtime key") } - token.Scopes = strings.Split(scopesString, ",") + token.CreateTime, err = dateparse.ParseLocal(createTime) + if err != nil { + return nil, err + } return token, nil } -// GetToken loads a token from repo config -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, id string) (*Token, error) { - return loadToken(repo, id, true) -} - -func listTokens(repo repository.RepoConfig, global bool) ([]string, error) { - readerFn := repo.ReadConfigs - if global { - readerFn = repo.ReadGlobalConfigs - } - - configs, err := readerFn(tokenConfigKeyPrefix + ".") +// 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.RepoCommon) ([]string, error) { + configs, err := repo.GlobalConfig().ReadAll(tokenConfigKeyPrefix + ".") if err != nil { return nil, err } @@ -181,66 +143,26 @@ func listTokens(repo repository.RepoConfig, global bool) ([]string, error) { return result, nil } -// 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 - } - - 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 { - storeFn := repo.StoreConfig - if token.Global { - storeFn = repo.StoreGlobalConfig - } - - storeValueKey := fmt.Sprintf("git-bug.token.%s.%s", token.Id(), tokenValueKey) - err := storeFn(storeValueKey, token.Value) +// StoreToken stores a token in the repo config +func StoreToken(repo repository.RepoCommon, token *Token) error { + storeValueKey := fmt.Sprintf("git-bug.token.%s.%s", token.ID.String(), tokenValueKey) + err := repo.GlobalConfig().StoreString(storeValueKey, token.Value) if err != nil { return err } - storeTargetKey := fmt.Sprintf("git-bug.token.%s.%s", token.Id(), tokenTargetKey) - err = storeFn(storeTargetKey, token.Target) + storeTargetKey := fmt.Sprintf("git-bug.token.%s.%s", token.ID.String(), tokenTargetKey) + err = repo.GlobalConfig().StoreString(storeTargetKey, token.Target) if err != nil { return err } - storeScopesKey := fmt.Sprintf("git-bug.token.%s.%s", token.Id(), tokenScopesKey) - return storeFn(storeScopesKey, strings.Join(token.Scopes, ",")) -} - -// StoreToken stores a token in the repo config -func StoreToken(repo repository.RepoConfig, token *Token) error { - return storeToken(repo, token) + createTimeKey := fmt.Sprintf("git-bug.token.%s.%s", token.ID.String(), tokenCreateTimeKey) + return repo.GlobalConfig().StoreString(createTimeKey, strconv.Itoa(int(token.CreateTime.Unix()))) } // RemoveToken removes a token from the repo config -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, id string) error { +func RemoveToken(repo repository.RepoCommon, id string) error { keyPrefix := fmt.Sprintf("git-bug.token.%s", id) - return repo.RmGlobalConfigs(keyPrefix) + return repo.GlobalConfig().RemoveAll(keyPrefix) } diff --git a/commands/bridge_token.go b/commands/bridge_token.go index cdae0664..7467691e 100644 --- a/commands/bridge_token.go +++ b/commands/bridge_token.go @@ -2,7 +2,7 @@ package commands import ( "fmt" - "strings" + "time" "github.com/spf13/cobra" @@ -10,7 +10,7 @@ import ( "github.com/MichaelMure/git-bug/cache" "github.com/MichaelMure/git-bug/util/colors" "github.com/MichaelMure/git-bug/util/interrupt" - "github.com/MichaelMure/git-bug/util/text" + text "github.com/MichaelMure/go-term-text" ) var ( @@ -31,14 +31,8 @@ func runTokenBridge(cmd *cobra.Command, args []string) error { return err } - for token, global := range tokens { - // TODO: filter tokens using flags - getTokenFn := core.GetToken - if global { - getTokenFn = core.GetGlobalToken - } - - token, err := getTokenFn(repo, token) + for _, token := range tokens { + token, err := core.LoadToken(repo, token) if err != nil { return err } @@ -49,17 +43,16 @@ func runTokenBridge(cmd *cobra.Command, args []string) error { } func printToken(token *core.Token) { - idFmt := text.LeftPadMaxLine(token.HumanId(), 7, 0) - valueFmt := text.LeftPadMaxLine(token.Value, 8, 0) - targetFmt := text.LeftPadMaxLine(token.Target, 8, 0) - scopesFmt := text.LeftPadMaxLine(strings.Join(token.Scopes, ","), 20, 0) + idFmt := text.LeftPadMaxLine(token.ID.Human(), 7, 0) + valueFmt := text.LeftPadMaxLine(token.Value, 15, 0) + targetFmt := text.LeftPadMaxLine(token.Target, 7, 0) + createTimeFmt := text.LeftPadMaxLine(token.CreateTime.Format(time.RFC822), 20, 0) - fmt.Printf("%s %s %s %s %s\n", + fmt.Printf("%s %s %s %s\n", idFmt, - valueFmt, colors.Magenta(targetFmt), - colors.Yellow(token.Kind()), - scopesFmt, + valueFmt, + createTimeFmt, ) } diff --git a/commands/bridge_token_add.go b/commands/bridge_token_add.go index 7b7a8964..58e9f472 100644 --- a/commands/bridge_token_add.go +++ b/commands/bridge_token_add.go @@ -8,17 +8,17 @@ import ( ) var ( - bridgeToken core.Token + bridgeTokenValue string + bridgeTokenTarget string ) func runBridgeTokenAdd(cmd *cobra.Command, args []string) error { - _ = bridgeToken.Id() // TODO: a better design to avoid doing this - - if err := bridgeToken.Validate(); err != nil { + token := core.NewToken(bridgeTokenValue, bridgeTokenTarget) + if err := token.Validate(); err != nil { return errors.Wrap(err, "invalid token") } - return core.StoreToken(repo, &bridgeToken) + return core.StoreToken(repo, token) } var bridgeTokenAddCmd = &cobra.Command{ @@ -31,9 +31,7 @@ var bridgeTokenAddCmd = &cobra.Command{ func init() { bridgeTokenCmd.AddCommand(bridgeTokenAddCmd) - bridgeTokenAddCmd.Flags().BoolVarP(&bridgeToken.Global, "global", "g", false, "") - bridgeTokenAddCmd.Flags().StringVarP(&bridgeToken.Value, "value", "v", "", "") - bridgeTokenAddCmd.Flags().StringVarP(&bridgeToken.Target, "target", "t", "", "") - bridgeTokenAddCmd.Flags().StringArrayVarP(&bridgeToken.Scopes, "scopes", "s", []string{}, "") + bridgeTokenAddCmd.Flags().StringVarP(&bridgeTokenValue, "value", "v", "", "") + bridgeTokenAddCmd.Flags().StringVarP(&bridgeTokenTarget, "target", "t", "", "") bridgeTokenAddCmd.Flags().SortFlags = false } diff --git a/commands/bridge_token_rm.go b/commands/bridge_token_rm.go index 29fdb4f2..7296f95a 100644 --- a/commands/bridge_token_rm.go +++ b/commands/bridge_token_rm.go @@ -7,13 +7,7 @@ import ( ) func runBridgeTokenRm(cmd *cobra.Command, args []string) error { - err := core.RemoveToken(repo, args[0]) - if err == nil { - return nil - } - - err = core.RemoveGlobalToken(repo, args[0]) - return err + return core.RemoveToken(repo, args[0]) } var bridgeTokenRmCmd = &cobra.Command{ |