mirror of
https://gitea.com/jolheiser/sip
synced 2024-11-22 11:41:59 +01:00
Move log in/out commands to tokens command
Signed-off-by: jolheiser <john.olheiser@gmail.com>
This commit is contained in:
parent
b0816086dd
commit
039c227402
11
README.md
11
README.md
@ -10,13 +10,12 @@ If no `upstream` repository is found, `upstream` becomes synonymous with `origin
|
||||
* Configuration `sip config`
|
||||
* Change the default `origin` remote name `sip config origin`
|
||||
* Change the default `upstream` remote name `sip config upstrea`
|
||||
* Login `sip login`
|
||||
* Add a user token for API usage
|
||||
* Generate a new token from CLI `sip login auto`
|
||||
* Tokens `sip tokens`
|
||||
* List current available access tokens
|
||||
* Generate a new token from CLI `sip token create <token>`
|
||||
* If `<token>` is present, add new access token, otherwise...
|
||||
* Authenticate with username/password to get a new token without leaving the terminal
|
||||
* List available logins `sip login list`
|
||||
* Logout `sip logout`
|
||||
* Remove user tokens
|
||||
* Remove access tokens `sip tokens remove`
|
||||
* Repository status `sip repo`
|
||||
* Get basic information about the `upstream` repository
|
||||
* Issue search `sip issues`
|
||||
|
32
cmd/cmd.go
32
cmd/cmd.go
@ -43,9 +43,9 @@ var (
|
||||
Value: getUpstreamRepo()[2],
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "login",
|
||||
Aliases: []string{"l"},
|
||||
Usage: "The login token to use (by name)",
|
||||
Name: "token",
|
||||
Aliases: []string{"t"},
|
||||
Usage: "The access token to use (by name)",
|
||||
},
|
||||
}
|
||||
originOnce sync.Once
|
||||
@ -55,38 +55,38 @@ var (
|
||||
)
|
||||
|
||||
func requireToken(ctx *cli.Context) (string, error) {
|
||||
if ctx.IsSet("login") {
|
||||
return getToken(ctx.String("login")), nil
|
||||
if ctx.IsSet("token") {
|
||||
return getToken(ctx.String("token")), nil
|
||||
}
|
||||
loginMap := make(map[string]config.Login)
|
||||
opts := make([]string, len(config.Logins))
|
||||
for idx, login := range config.Logins {
|
||||
key := fmt.Sprintf("%s (%s)", login.Name, login.URL)
|
||||
loginMap[key] = login
|
||||
tokenMap := make(map[string]config.Token)
|
||||
opts := make([]string, len(config.Tokens))
|
||||
for idx, token := range config.Tokens {
|
||||
key := fmt.Sprintf("%s (%s)", token.Name, token.URL)
|
||||
tokenMap[key] = token
|
||||
opts[idx] = key
|
||||
}
|
||||
|
||||
question := &survey.Select{Message: "This action requires a login token", Options: opts}
|
||||
question := &survey.Select{Message: "This action requires an access token", Options: opts}
|
||||
var answer string
|
||||
|
||||
if err := survey.AskOne(question, &answer); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return loginMap[answer].Token, nil
|
||||
return tokenMap[answer].Token, nil
|
||||
}
|
||||
|
||||
func getToken(name string) string {
|
||||
for _, login := range config.Logins {
|
||||
if name == login.Name {
|
||||
return login.Token
|
||||
for _, token := range config.Tokens {
|
||||
if name == token.Name {
|
||||
return token.Token
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getClient(ctx *cli.Context) *gitea.Client {
|
||||
return gitea.NewClient(ctx.String("url"), getToken(ctx.String("login")))
|
||||
return gitea.NewClient(ctx.String("url"), getToken(ctx.String("token")))
|
||||
}
|
||||
|
||||
func getUpstreamRepo() []string {
|
||||
|
152
cmd/login.go
152
cmd/login.go
@ -1,152 +0,0 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"errors"
|
||||
"gitea.com/jolheiser/beaver"
|
||||
"gitea.com/jolheiser/sip/modules/config"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
Login = cli.Command{
|
||||
Name: "login",
|
||||
Usage: "Log in to a Gitea server",
|
||||
Action: doLogin,
|
||||
Subcommands: []*cli.Command{
|
||||
{
|
||||
Name: "auto",
|
||||
Usage: "Create a new token via API",
|
||||
Action: doLoginAuto,
|
||||
},
|
||||
{
|
||||
Name: "list",
|
||||
Usage: "List available tokens",
|
||||
Action: doLoginList,
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func doLogin(ctx *cli.Context) error {
|
||||
questions := []*survey.Question{
|
||||
{
|
||||
Name: "name",
|
||||
Prompt: &survey.Input{Message: "Name for this login"},
|
||||
Validate: validateLoginName,
|
||||
},
|
||||
{
|
||||
Name: "url",
|
||||
Prompt: &survey.Input{Message: "URL for the Gitea instance", Default: ctx.String("url")},
|
||||
Validate: survey.Required,
|
||||
},
|
||||
{
|
||||
Name: "token",
|
||||
Prompt: &survey.Input{Message: "API Token"},
|
||||
Validate: survey.Required,
|
||||
},
|
||||
}
|
||||
answers := struct {
|
||||
Name string
|
||||
URL string
|
||||
Token string
|
||||
}{}
|
||||
|
||||
if err := survey.Ask(questions, &answers); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config.Logins = append(config.Logins, config.Login{
|
||||
Name: answers.Name,
|
||||
URL: answers.URL,
|
||||
Token: answers.Token,
|
||||
})
|
||||
|
||||
if err := config.Save(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
beaver.Infof("Login saved! You can refer to it by using `--login %s` with commands!", answers.Name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func doLoginAuto(ctx *cli.Context) error {
|
||||
questions := []*survey.Question{
|
||||
{
|
||||
Name: "name",
|
||||
Prompt: &survey.Input{Message: "Name for this login", Default: "gitea"},
|
||||
Validate: validateLoginName,
|
||||
},
|
||||
{
|
||||
Name: "token",
|
||||
Prompt: &survey.Input{Message: "Name for this token", Default: "sip"},
|
||||
Validate: survey.Required,
|
||||
},
|
||||
{
|
||||
Name: "url",
|
||||
Prompt: &survey.Input{Message: "URL for the Gitea instance", Default: ctx.String("url")},
|
||||
Validate: survey.Required,
|
||||
},
|
||||
{
|
||||
Name: "username",
|
||||
Prompt: &survey.Input{Message: "Username the Gitea instance"},
|
||||
Validate: survey.Required,
|
||||
},
|
||||
{
|
||||
Name: "password",
|
||||
Prompt: &survey.Password{Message: "Password for the Gitea instance"},
|
||||
Validate: survey.Required,
|
||||
},
|
||||
}
|
||||
answers := struct {
|
||||
Name string
|
||||
Token string
|
||||
URL string
|
||||
Username string
|
||||
Password string
|
||||
}{}
|
||||
|
||||
if err := survey.Ask(questions, &answers); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client := gitea.NewClient(answers.URL, "")
|
||||
|
||||
token, err := client.CreateAccessToken(answers.Username, answers.Password, gitea.CreateAccessTokenOption{Name: answers.Token})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config.Logins = append(config.Logins, config.Login{
|
||||
Name: answers.Name,
|
||||
URL: answers.URL,
|
||||
Token: token.Token,
|
||||
})
|
||||
|
||||
if err := config.Save(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
beaver.Infof("Login saved! You can refer to it by using `--login %s` with commands!", answers.Name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func doLoginList(ctx *cli.Context) error {
|
||||
for idx, login := range config.Logins {
|
||||
beaver.Infof("%d. %s (%s)", idx+1, login.Name, login.URL)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateLoginName(ans interface{}) error {
|
||||
name := ans.(string)
|
||||
for _, login := range config.Logins {
|
||||
if name == login.Name {
|
||||
return errors.New("login name already exists")
|
||||
}
|
||||
}
|
||||
return survey.Required(ans)
|
||||
}
|
25
cmd/token.go
Normal file
25
cmd/token.go
Normal file
@ -0,0 +1,25 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"gitea.com/jolheiser/beaver"
|
||||
"gitea.com/jolheiser/sip/modules/config"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var Tokens = cli.Command{
|
||||
Name: "tokens",
|
||||
Aliases: []string{"token"},
|
||||
Usage: "Manage access tokens",
|
||||
Action: doTokenList,
|
||||
Subcommands: []*cli.Command{
|
||||
&TokensAdd,
|
||||
&TokensRemove,
|
||||
},
|
||||
}
|
||||
|
||||
func doTokenList(ctx *cli.Context) error {
|
||||
for idx, token := range config.Tokens {
|
||||
beaver.Infof("%d. %s (%s)", idx+1, token.Name, token.URL)
|
||||
}
|
||||
return nil
|
||||
}
|
101
cmd/token_add.go
Normal file
101
cmd/token_add.go
Normal file
@ -0,0 +1,101 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"errors"
|
||||
"gitea.com/jolheiser/beaver"
|
||||
"gitea.com/jolheiser/sip/modules/config"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var TokensAdd = cli.Command{
|
||||
Name: "add",
|
||||
Usage: "Add a new access token",
|
||||
Action: doTokenAdd,
|
||||
}
|
||||
|
||||
func doTokenAdd(ctx *cli.Context) error {
|
||||
token := ctx.Args().First()
|
||||
questions := []*survey.Question{
|
||||
{
|
||||
Name: "name",
|
||||
Prompt: &survey.Input{Message: "Local nickname for this token", Default: "gitea"},
|
||||
Validate: validateTokenName,
|
||||
},
|
||||
{
|
||||
Name: "token",
|
||||
Prompt: &survey.Input{Message: "Name for this token in Gitea", Default: "sip"},
|
||||
Validate: survey.Required,
|
||||
},
|
||||
{
|
||||
Name: "url",
|
||||
Prompt: &survey.Input{Message: "URL for the Gitea instance", Default: ctx.String("url")},
|
||||
Validate: survey.Required,
|
||||
},
|
||||
}
|
||||
answers := struct {
|
||||
Name string
|
||||
Token string
|
||||
URL string
|
||||
}{}
|
||||
|
||||
if err := survey.Ask(questions, &answers); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if token == "" {
|
||||
authQuestions := []*survey.Question{
|
||||
{
|
||||
Name: "username",
|
||||
Prompt: &survey.Input{Message: "Username the Gitea instance"},
|
||||
Validate: survey.Required,
|
||||
},
|
||||
{
|
||||
Name: "password",
|
||||
Prompt: &survey.Password{Message: "Password for the Gitea instance"},
|
||||
Validate: survey.Required,
|
||||
},
|
||||
}
|
||||
authAnswers := struct {
|
||||
Username string
|
||||
Password string
|
||||
}{}
|
||||
|
||||
if err := survey.Ask(authQuestions, &authAnswers); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client := gitea.NewClient(answers.URL, "")
|
||||
|
||||
t, err := client.CreateAccessToken(authAnswers.Username, authAnswers.Password, gitea.CreateAccessTokenOption{Name: answers.Token})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
token = t.Token
|
||||
}
|
||||
|
||||
config.Tokens = append(config.Tokens, config.Token{
|
||||
Name: answers.Name,
|
||||
URL: answers.URL,
|
||||
Token: token,
|
||||
})
|
||||
|
||||
if err := config.Save(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
beaver.Infof("Token saved! You can refer to it by using `--token %s` with commands!", answers.Name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateTokenName(ans interface{}) error {
|
||||
name := ans.(string)
|
||||
for _, token := range config.Tokens {
|
||||
if name == token.Name {
|
||||
return errors.New("token already exists")
|
||||
}
|
||||
}
|
||||
return survey.Required(ans)
|
||||
}
|
@ -8,18 +8,16 @@ import (
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
Logout = cli.Command{
|
||||
Name: "logout",
|
||||
Usage: "Log out of a Gitea server",
|
||||
Action: doLogout,
|
||||
}
|
||||
)
|
||||
var TokensRemove = cli.Command{
|
||||
Name: "remove",
|
||||
Usage: "Remove access tokens",
|
||||
Action: doTokenRemove,
|
||||
}
|
||||
|
||||
func doLogout(ctx *cli.Context) error {
|
||||
opts := make([]string, len(config.Logins))
|
||||
for idx, login := range config.Logins {
|
||||
opts[idx] = fmt.Sprintf("%s (%s)", login.Name, login.URL)
|
||||
func doTokenRemove(ctx *cli.Context) error {
|
||||
opts := make([]string, len(config.Tokens))
|
||||
for idx, token := range config.Tokens {
|
||||
opts[idx] = fmt.Sprintf("%s (%s)", token.Name, token.URL)
|
||||
}
|
||||
question := &survey.MultiSelect{
|
||||
Message: "Which would you like to remove?",
|
||||
@ -34,22 +32,22 @@ func doLogout(ctx *cli.Context) error {
|
||||
|
||||
idxs := make([]int, len(answers))
|
||||
for idx, answer := range answers {
|
||||
for idy, login := range config.Logins {
|
||||
if answer == fmt.Sprintf("%s (%s)", login.Name, login.URL) {
|
||||
for idy, token := range config.Tokens {
|
||||
if answer == fmt.Sprintf("%s (%s)", token.Name, token.URL) {
|
||||
idxs[len(answers)-idx-1] = idy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, idx := range idxs {
|
||||
config.Logins = append(config.Logins[:idx], config.Logins[idx+1:]...)
|
||||
config.Tokens = append(config.Tokens[:idx], config.Tokens[idx+1:]...)
|
||||
}
|
||||
|
||||
if err := config.Save(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
beaver.Infof("Logged out of %d accounts! Remember to clean up your tokens!", len(answers))
|
||||
beaver.Infof("Removed %d token(s)! Remember to clean up in Gitea if necessary!", len(answers))
|
||||
|
||||
return nil
|
||||
}
|
3
main.go
3
main.go
@ -16,8 +16,7 @@ func main() {
|
||||
app.Version = Version
|
||||
app.Commands = []*cli.Command{
|
||||
&cmd.Config,
|
||||
&cmd.Login,
|
||||
&cmd.Logout,
|
||||
&cmd.Tokens,
|
||||
&cmd.Repo,
|
||||
&cmd.Issues,
|
||||
&cmd.Pulls,
|
||||
|
@ -15,16 +15,16 @@ var (
|
||||
|
||||
Origin string
|
||||
Upstream string
|
||||
Logins []Login
|
||||
Tokens []Token
|
||||
)
|
||||
|
||||
type config struct {
|
||||
Origin string `toml:"origin"`
|
||||
Upstream string `toml:"upstream"`
|
||||
Logins []Login `toml:"login"`
|
||||
Tokens []Token `toml:"token"`
|
||||
}
|
||||
|
||||
type Login struct {
|
||||
type Token struct {
|
||||
Name string `toml:"name"`
|
||||
URL string `toml:"url"`
|
||||
Token string `toml:"token"`
|
||||
@ -53,13 +53,13 @@ func init() {
|
||||
|
||||
Origin = cfg.Origin
|
||||
Upstream = cfg.Upstream
|
||||
Logins = cfg.Logins
|
||||
Tokens = cfg.Tokens
|
||||
}
|
||||
|
||||
func Save() error {
|
||||
cfg.Origin = Origin
|
||||
cfg.Upstream = Upstream
|
||||
cfg.Logins = Logins
|
||||
cfg.Tokens = Tokens
|
||||
|
||||
fi, err := os.Create(configPath)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user