mirror of
https://codeberg.org/shroff/phylum.git
synced 2026-04-25 22:19:35 -05:00
173 lines
4.5 KiB
Go
173 lines
4.5 KiB
Go
package keys
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"codeberg.org/shroff/phylum/server/internal/auth"
|
|
"codeberg.org/shroff/phylum/server/internal/command/common"
|
|
"codeberg.org/shroff/phylum/server/internal/db"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
func SetupCommand() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "keys",
|
|
Short: "Manager API Keys",
|
|
}
|
|
|
|
cmd.AddCommand(
|
|
setupGenerateCommand(),
|
|
setupListCommand(),
|
|
setupRevokeCommand(),
|
|
)
|
|
|
|
return cmd
|
|
}
|
|
|
|
func setupGenerateCommand() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "generate",
|
|
Short: "Generate New API Key/Token",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
u := common.User(cmd)
|
|
if u == nil {
|
|
fmt.Println("unable to generate API key: user not specified")
|
|
os.Exit(1)
|
|
}
|
|
validity, _ := cmd.Flags().GetDuration("validity")
|
|
description, _ := cmd.Flags().GetString("description")
|
|
reader := bufio.NewReader(os.Stdin)
|
|
if description == "" {
|
|
fmt.Print("Description: ")
|
|
if val, err := reader.ReadString('\n'); err != nil {
|
|
fmt.Println("failed to read scopes: " + err.Error())
|
|
os.Exit(1)
|
|
} else if len(strings.TrimSpace(val)) == 0 {
|
|
description = "Generated via CLI"
|
|
} else {
|
|
|
|
}
|
|
}
|
|
var scopes []string
|
|
if len(scopes) == 0 {
|
|
name, _ := cmd.Flags().GetString("name")
|
|
if name == "" {
|
|
fmt.Print("Comma-separated scopes [*]: ")
|
|
if val, err := reader.ReadString('\n'); err != nil {
|
|
fmt.Println("failed to read scopes: " + err.Error())
|
|
os.Exit(1)
|
|
} else if len(strings.TrimSpace(val)) == 0 {
|
|
scopes = []string{"*"}
|
|
} else {
|
|
scopes = strings.Split(val, ",")
|
|
for i, s := range scopes {
|
|
scopes[i] = strings.TrimSpace(s)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if err := db.Get(context.Background()).RunInTx(func(db db.TxHandler) error {
|
|
if token, _ := cmd.Flags().GetBool("token"); token {
|
|
if token, err := auth.GenerateAPIToken(db, u.ID, validity, description, scopes); err != nil {
|
|
return err
|
|
} else {
|
|
fmt.Println(token)
|
|
return nil
|
|
}
|
|
} else {
|
|
if id, key, err := auth.GenerateAPIKey(db, u.ID, validity, description, scopes); err != nil {
|
|
return err
|
|
} else {
|
|
fmt.Println("Key ID:", id)
|
|
fmt.Println(" Key:", key)
|
|
return nil
|
|
}
|
|
}
|
|
}); err != nil {
|
|
fmt.Println("unable to generate API key: " + err.Error())
|
|
os.Exit(1)
|
|
}
|
|
},
|
|
}
|
|
|
|
cmd.Flags().BoolP("token", "t", false, "Generate API token instead of ID:Key pair")
|
|
cmd.Flags().Duration("validity", time.Duration(0), "Validity of API Key (0 means never)")
|
|
cmd.Flags().String("description", "", "Validity of API Key (0 means never)")
|
|
cmd.Flags().StringSlice("scopes", []string{}, "Scopes")
|
|
return cmd
|
|
}
|
|
|
|
func setupListCommand() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "list",
|
|
Short: "List API Keys",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
u := common.User(cmd)
|
|
if u == nil {
|
|
fmt.Println("unable to list API Keys: user not specified")
|
|
os.Exit(1)
|
|
}
|
|
showExpired, _ := cmd.Flags().GetBool("show-expired")
|
|
keys, err := auth.ListAPIKeys(db.Get(context.Background()), u.ID, showExpired)
|
|
if err != nil {
|
|
fmt.Println("unable to list API keys: " + err.Error())
|
|
}
|
|
for _, k := range keys {
|
|
fmt.Println(k.ID + " [" + k.Description + "]")
|
|
fmt.Println("Created:", k.Created.Format(time.DateTime))
|
|
expires := "Never"
|
|
if k.Expires.Valid {
|
|
expires = k.Expires.Time.Format(time.DateTime)
|
|
if k.Expires.Time.Before(time.Now()) {
|
|
expires += " [X]"
|
|
}
|
|
}
|
|
fmt.Println("Expires:", expires)
|
|
fmt.Println(" Scopes:", strings.Join(k.Scopes, ", "))
|
|
fmt.Println()
|
|
}
|
|
},
|
|
}
|
|
|
|
cmd.Flags().BoolP("show-expired", "x", false, "Show Expired Keys")
|
|
|
|
return cmd
|
|
}
|
|
|
|
func setupRevokeCommand() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "revoke <id>...",
|
|
Short: "Revoke API Keys",
|
|
Args: cobra.MinimumNArgs(1),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
u := common.User(cmd)
|
|
if u == nil {
|
|
fmt.Println("unable to revoke API Keys: user not specified")
|
|
os.Exit(1)
|
|
}
|
|
delete, _ := cmd.Flags().GetBool("delete")
|
|
err := db.RunInTx(context.Background(), func(db db.TxHandler) error {
|
|
for _, k := range args {
|
|
if err := auth.RevokeAPIKey(db, k, delete); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
fmt.Println("failed to revoke some keys: " + err.Error())
|
|
os.Exit(1)
|
|
}
|
|
},
|
|
}
|
|
cmd.Flags().Bool("delete", false, "Delete from DB")
|
|
|
|
return cmd
|
|
}
|