features/working-on-scopes #13

Merged
jtom38 merged 28 commits from features/working-on-scopes into main 2024-04-04 15:31:54 -07:00
Showing only changes of commit f591dadd3b - Show all commits

View File

@ -5,8 +5,6 @@ import (
"go-cook/api/domain" "go-cook/api/domain"
"go-cook/api/repositories" "go-cook/api/repositories"
"net/http" "net/http"
"strings"
"time"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
@ -20,91 +18,6 @@ const (
ErrUserNotFound = "requested user does not exist" ErrUserNotFound = "requested user does not exist"
) )
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
}
func (h *Handler) AuthRegister(c echo.Context) error { func (h *Handler) AuthRegister(c echo.Context) error {
username := c.QueryParam("username") username := c.QueryParam("username")
_, err := h.userRepo.GetByName(username) _, err := h.userRepo.GetByName(username)
@ -145,16 +58,7 @@ func (h *Handler) AuthLogin(c echo.Context) error {
// Check to see if they are trying to login with the admin token // Check to see if they are trying to login with the admin token
if username == "" { if username == "" {
if h.Config.AdminToken != password { return h.validateAdminToken(c, password)
return h.ReturnUnauthorizedResponse(c, ErrUserNotFound)
}
token, err := h.generateAdminJwt("admin")
if err != nil {
return h.InternalServerErrorResponse(c, err.Error())
}
return c.JSON(http.StatusOK, token)
} }
// check if the user exists // check if the user exists
@ -177,6 +81,19 @@ func (h *Handler) AuthLogin(c echo.Context) error {
return c.JSON(http.StatusOK, token) return c.JSON(http.StatusOK, token)
} }
func (h *Handler) validateAdminToken(c echo.Context, password string) error {
if h.Config.AdminToken != password {
return h.ReturnUnauthorizedResponse(c, ErrUserNotFound)
}
token, err := h.generateAdminJwt("admin")
if err != nil {
return h.InternalServerErrorResponse(c, err.Error())
}
return c.JSON(http.StatusOK, token)
}
//func (h *Handler) AddScope(c echo.Context) error { //func (h *Handler) AddScope(c echo.Context) error {
// //
//} //}