Refactor everything again
This commit is contained in:
parent
7fdb0bf0f4
commit
96c369e4b1
14 changed files with 72 additions and 53 deletions
40
internal/app/find.go
Normal file
40
internal/app/find.go
Normal 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
50
internal/app/root.go
Normal 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
48
internal/app/serve.go
Normal 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
58
internal/app/verify.go
Normal 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)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue