From 593ce11c6b9df8fbce4e0c98160e57332c04fb52 Mon Sep 17 00:00:00 2001 From: James Tombleson Date: Sun, 31 Mar 2024 18:09:24 -0700 Subject: [PATCH] moved jwt things to its own file --- api/handlers/v1/jwt.go | 95 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 api/handlers/v1/jwt.go diff --git a/api/handlers/v1/jwt.go b/api/handlers/v1/jwt.go new file mode 100644 index 0000000..58d1bef --- /dev/null +++ b/api/handlers/v1/jwt.go @@ -0,0 +1,95 @@ +package v1 + +import ( + "errors" + "go-cook/api/domain" + "strings" + "time" + + "github.com/golang-jwt/jwt/v5" +) + +type JwtToken struct { + Exp time.Time `json:"exp"` + Iss string `json:"iss"` + Authorized bool `json:"authorized"` + UserName string `json:"username"` + Scopes []string `json:"scopes"` + jwt.RegisteredClaims +} + +func (j JwtToken) IsValid(scope string) error { + err := j.hasExpired() + if err != nil { + return err + } + + err = j.hasScope(scope) + if err != nil { + return err + } + + return nil +} + +func (j JwtToken) hasExpired() error { + // Check to see if the token has expired + hasExpired := j.Exp.Compare(time.Now()) + if hasExpired == -1 { + return errors.New(ErrJwtExpired) + } + return nil +} + +func (j JwtToken) hasScope(scope string) error { + // they have the scope to access everything, so let them pass. + if strings.Contains(domain.ScopeAll, scope) { + return nil + } + + for _, s := range j.Scopes { + if strings.Contains(s, scope) { + return nil + } + } + return errors.New(ErrJwtScopeMissing) +} + +func (h *Handler) generateJwt(username string) (string, error) { + secret := []byte(h.Config.JwtSecret) + + token := jwt.New(jwt.SigningMethodHS256) + claims := token.Claims.(jwt.MapClaims) + claims["exp"] = time.Now().Add(10 * time.Minute) + claims["authorized"] = true + claims["username"] = username + + var scopes []string + scopes = append(scopes, domain.ScopeRecipeRead) + claims["scopes"] = scopes + + tokenString, err := token.SignedString(secret) + if err != nil { + return "", err + } + + return tokenString, nil +} + +func (h *Handler) generateAdminJwt(username string) (string, error) { + secret := []byte(h.Config.JwtSecret) + + token := jwt.New(jwt.SigningMethodHS256) + claims := token.Claims.(jwt.MapClaims) + claims["exp"] = time.Now().Add(10 * time.Minute) + claims["authorized"] = true + claims["username"] = username + claims["scopes"] = domain.ScopeAll + + tokenString, err := token.SignedString(secret) + if err != nil { + return "", err + } + + return tokenString, nil +}