soft-serve

Fork https://github.com/charmbracelet/soft-serve

git clone git://git.lin.moe/go/soft-serve.git

  1package cmd
  2
  3import (
  4	"strconv"
  5	"strings"
  6	"time"
  7
  8	"github.com/caarlos0/duration"
  9	"github.com/charmbracelet/soft-serve/pkg/backend"
 10	"github.com/charmbracelet/soft-serve/pkg/proto"
 11	"github.com/dustin/go-humanize"
 12	"github.com/spf13/cobra"
 13)
 14
 15// TokenCommand returns a command that manages user access tokens.
 16func TokenCommand() *cobra.Command {
 17	cmd := &cobra.Command{
 18		Use:     "token",
 19		Aliases: []string{"access-token"},
 20		Short:   "Manage access tokens",
 21	}
 22
 23	var createExpiresIn string
 24	createCmd := &cobra.Command{
 25		Use:   "create NAME",
 26		Short: "Create a new access token",
 27		Args:  cobra.MinimumNArgs(1),
 28		RunE: func(cmd *cobra.Command, args []string) error {
 29			ctx := cmd.Context()
 30			be := backend.FromContext(ctx)
 31			name := strings.Join(args, " ")
 32
 33			user := proto.UserFromContext(ctx)
 34			if user == nil {
 35				return proto.ErrUserNotFound
 36			}
 37
 38			var expiresAt time.Time
 39			var expiresIn time.Duration
 40			if createExpiresIn != "" {
 41				d, err := duration.Parse(createExpiresIn)
 42				if err != nil {
 43					return err
 44				}
 45
 46				expiresIn = d
 47				expiresAt = time.Now().Add(d)
 48			}
 49
 50			token, err := be.CreateAccessToken(ctx, user, name, expiresAt)
 51			if err != nil {
 52				return err
 53			}
 54
 55			notice := "Access token created"
 56			if expiresIn != 0 {
 57				notice += " (expires in " + humanize.Time(expiresAt) + ")"
 58			}
 59
 60			cmd.PrintErrln(notice)
 61			cmd.Println(token)
 62
 63			return nil
 64		},
 65	}
 66
 67	createCmd.Flags().StringVar(&createExpiresIn, "expires-in", "", "Token expiration time (e.g. 1y, 3mo, 2w, 5d4h, 1h30m)")
 68
 69	listCmd := &cobra.Command{
 70		Use:     "list",
 71		Aliases: []string{"ls"},
 72		Short:   "List access tokens",
 73		Args:    cobra.NoArgs,
 74		RunE: func(cmd *cobra.Command, _ []string) error {
 75			ctx := cmd.Context()
 76			be := backend.FromContext(ctx)
 77
 78			user := proto.UserFromContext(ctx)
 79			if user == nil {
 80				return proto.ErrUserNotFound
 81			}
 82
 83			tokens, err := be.ListAccessTokens(ctx, user)
 84			if err != nil {
 85				return err
 86			}
 87
 88			if len(tokens) == 0 {
 89				cmd.Println("No tokens found")
 90				return nil
 91			}
 92
 93			now := time.Now()
 94			for _, token := range tokens {
 95				expiresAt := "forever"
 96				if !token.ExpiresAt.IsZero() {
 97					expiresAt = token.ExpiresAt.Format(time.RFC3339)
 98					if now.After(token.ExpiresAt) {
 99						expiresAt += "(expired)"
100					}
101				}
102				cmd.Printf("[%d]%s: %s - %s\n",
103					token.ID, token.Name,
104					token.CreatedAt.Format(time.RFC3339), expiresAt)
105			}
106
107			return nil
108		},
109	}
110
111	deleteCmd := &cobra.Command{
112		Use:     "delete ID",
113		Aliases: []string{"rm", "remove"},
114		Short:   "Delete an access token",
115		Args:    cobra.ExactArgs(1),
116		RunE: func(cmd *cobra.Command, args []string) error {
117			ctx := cmd.Context()
118			be := backend.FromContext(ctx)
119
120			user := proto.UserFromContext(ctx)
121			if user == nil {
122				return proto.ErrUserNotFound
123			}
124
125			id, err := strconv.ParseInt(args[0], 10, 64)
126			if err != nil {
127				return err
128			}
129
130			if err := be.DeleteAccessToken(ctx, user, id); err != nil {
131				return err
132			}
133
134			cmd.PrintErrln("Access token deleted")
135			return nil
136		},
137	}
138
139	cmd.AddCommand(
140		createCmd,
141		listCmd,
142		deleteCmd,
143	)
144
145	return cmd
146}