Refactor everything again

This commit is contained in:
Andrew-71 2024-10-13 21:03:44 +03:00
parent 7fdb0bf0f4
commit 96c369e4b1
14 changed files with 72 additions and 53 deletions

40
internal/app/find.go Normal file
View file

@ -0,0 +1,40 @@
package app
import (
"fmt"
"git.a71.su/Andrew71/pye/internal/models/user"
"git.a71.su/Andrew71/pye/internal/storage"
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(findUserCmd)
}
var findUserCmd = &cobra.Command{
Use: "find <uuid/email> <query>",
Short: "Find a user",
Long: `Find information about a user from their UUID or email`,
Args: cobra.ExactArgs(2),
Run: findUser,
}
func findUser(cmd *cobra.Command, args []string) {
var user user.User
var ok bool
if args[0] == "email" {
user, ok = storage.Data.ByEmail(args[1])
} else if args[0] == "uuid" {
user, ok = storage.Data.ById(args[1])
} else {
fmt.Println("Expected email or uuid")
return
}
if !ok {
fmt.Println("User not found")
} else {
fmt.Printf("Information for user:\nuuid\t- %s\nemail\t- %s\nhash\t- %s\n",
user.Uuid, user.Email, user.Hash)
}
}

50
internal/app/root.go Normal file
View file

@ -0,0 +1,50 @@
package app
import (
"fmt"
"os"
"git.a71.su/Andrew71/pye/internal/auth"
"git.a71.su/Andrew71/pye/internal/config"
"git.a71.su/Andrew71/pye/internal/logging"
"git.a71.su/Andrew71/pye/internal/storage"
"git.a71.su/Andrew71/pye/internal/storage/sqlite"
"github.com/spf13/cobra"
)
var rootCmd = &cobra.Command{
Use: "pye",
Short: "Pye is a simple JWT system",
Long: `A bare-bones authentication system with RS256`,
}
var (
cfgFile string
cfgDb string
debugMode *bool
)
func initConfig() {
logging.Load(*debugMode)
config.MustLoad(cfgFile)
if cfgDb != "" {
config.Cfg.SQLiteFile = cfgDb
}
auth.MustLoadKey()
storage.Data = sqlite.MustLoad(config.Cfg.SQLiteFile)
}
func init() {
cobra.OnInitialize(initConfig)
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "config.json", "config file")
rootCmd.PersistentFlags().StringVar(&cfgDb, "db", "", "database to use")
debugMode = rootCmd.PersistentFlags().BoolP("debug", "d", false, "enable debug mode")
}
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

48
internal/app/serve.go Normal file
View file

@ -0,0 +1,48 @@
package app
import (
"log/slog"
"net/http"
"strconv"
"git.a71.su/Andrew71/pye/internal/auth"
"git.a71.su/Andrew71/pye/internal/config"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"github.com/spf13/cobra"
)
var port int
func init() {
serveCmd.Flags().IntVarP(&port, "port", "p", 0, "port to use")
rootCmd.AddCommand(serveCmd)
}
var serveCmd = &cobra.Command{
Use: "serve",
Short: "Start JWT service",
Long: `Start a simple authentication service`,
Run: serveAuth,
}
func serveAuth(cmd *cobra.Command, args []string) {
if port == 0 {
port = config.Cfg.Port
}
r := chi.NewRouter()
r.Use(middleware.RealIP)
r.Use(middleware.Logger, middleware.CleanPath, middleware.StripSlashes)
r.Get("/pem", auth.ServePublicKey)
r.Post("/register", auth.Register)
r.Post("/login", auth.Login)
// Note: likely temporary, possibly to be replaced by a fake "frontend"
r.Get("/register", auth.Register)
r.Get("/login", auth.Login)
slog.Info("🪐 pye started", "port", port)
http.ListenAndServe(":"+strconv.Itoa(port), r)
}

58
internal/app/verify.go Normal file
View file

@ -0,0 +1,58 @@
package app
import (
"fmt"
"log/slog"
"os"
"git.a71.su/Andrew71/pye/internal/auth"
"github.com/golang-jwt/jwt/v5"
"github.com/spf13/cobra"
)
var (
verifyToken string
verifyFile string
)
func init() {
verifyCmd.Flags().StringVarP(&verifyToken, "token", "t", "", "token to verify")
verifyCmd.MarkFlagRequired("token")
verifyCmd.Flags().StringVarP(&verifyFile, "file", "f", "", "PEM file to use")
rootCmd.AddCommand(verifyCmd)
}
var verifyCmd = &cobra.Command{
Use: "verify",
Short: "Verify a JWT token",
Long: `Pass a JWT token (and optionally a path to a PEM-formatted file with the public key)
to verify whether it is valid.`,
Run: verifyFunc,
}
func verifyFunc(cmd *cobra.Command, args []string) {
if verifyToken == "" {
fmt.Println("Empty token supplied!")
return
}
var t *jwt.Token
var err error
if verifyFile == "" {
fmt.Println("No PEM file supplied, assuming local")
t, err = auth.VerifyLocal(verifyToken)
} else {
key, err_k := os.ReadFile(verifyFile)
if err_k != nil {
slog.Error("error reading file", "error", err, "file", verifyFile)
return
}
t, err = auth.Verify(verifyToken, key)
}
slog.Debug("result", "token", t, "error", err, "ok", err == nil)
if err == nil {
fmt.Println("Token valid!")
} else {
fmt.Println("Token invalid!", err)
}
}