Basic JWT is now working #12

Merged
jtom38 merged 12 commits from features/jwt/maybe into main 2024-03-29 14:51:01 -07:00
4 changed files with 141 additions and 7 deletions
Showing only changes of commit d2d524ac4e - Show all commits

99
api/handlers/v1/auth.go Normal file
View File

@ -0,0 +1,99 @@
package v1
import (
"go-cook/api/models"
"go-cook/api/repositories"
"net/http"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/labstack/echo/v4"
)
type JwtToken struct {
Exp time.Time `json:"exp"`
Authorized bool `json:"authorized"`
UserName string `json:"username"`
Token string `json:"token"`
jwt.RegisteredClaims
}
func generateJwt() (string, error) {
//TODO use env here
secret := []byte("ThisIsABadSecretDontReallyUseThis")
token := jwt.New(jwt.SigningMethodEdDSA)
claims := token.Claims.(jwt.MapClaims)
claims["exp"] = time.Now().Add(10 * time.Minute)
claims["authorized"] = true
claims["username"] = "someone"
tokenString, err := token.SignedString(secret)
if err != nil {
return "", err
}
return tokenString, nil
}
func (h *Handler) AuthRegister(c echo.Context) error {
username := c.QueryParam("username")
_, err := h.userRepo.GetByName(username)
if err != nil {
// if we have an err, validate that if its not user not found.
// if the user is not found, we can use that name
if err.Error() != repositories.ErrUserNotFound {
return c.JSON(http.StatusInternalServerError, models.ErrorResponse{
HttpCode: http.StatusInternalServerError,
Message: err.Error(),
})
}
}
password := c.QueryParam("password")
err = h.UserService.CheckPasswordForRequirements(password)
if err != nil {
return c.JSON(http.StatusInternalServerError, models.ErrorResponse{
HttpCode: http.StatusInternalServerError,
Message: err.Error(),
})
}
_, err = h.userRepo.Create(username, password)
if err != nil {
return c.JSON(http.StatusInternalServerError, models.ErrorResponse{
HttpCode: http.StatusInternalServerError,
Message: err.Error(),
})
}
return nil
}
func (h *Handler) AuthLogin(c echo.Context) error {
username := c.QueryParam("username")
password := c.QueryParam("password")
// check if the user exists
err := h.UserService.DoesUserExist(username)
if err != nil {
return c.JSON(http.StatusInternalServerError, err)
}
// make sure the hash matches
err = h.UserService.DoesPasswordMatchHash(username, password)
if err != nil {
return c.JSON(http.StatusInternalServerError, err)
}
token, err := generateJwt()
if err != nil {
return c.JSON(http.StatusInternalServerError, err)
}
return c.JSON(http.StatusOK, token)
}
func (h *Handler) RefreshJwtToken(c echo.Context) error {
return nil
}

View File

@ -47,3 +47,8 @@ func (h *Handler) HelloBody(c echo.Context) error {
Message: fmt.Sprintf("Hello, %s", request.Name),
})
}
func (h *Handler) ProtectedRoute(c echo.Context)error {
return nil
}

View File

@ -3,26 +3,52 @@ package v1
import (
"database/sql"
"go-cook/api/repositories"
"go-cook/api/services"
"github.com/golang-jwt/jwt/v5"
echojwt "github.com/labstack/echo-jwt/v4"
"github.com/labstack/echo/v4"
)
type Handler struct {
userRepo repositories.UserRepository
UserService services.UserService
userRepo repositories.IUserTable
recipeRepo repositories.IRecipeTable
}
func NewHandler(conn *sql.DB) *Handler {
return &Handler{
userRepo: repositories.NewUserRepository(conn),
UserService: services.NewUserService(conn),
userRepo: repositories.NewUserRepository(conn),
recipeRepo: repositories.NewRecipeRepository(conn),
}
}
func (h *Handler) Register(v1 *echo.Group) {
jwtConfig := echojwt.Config{
NewClaimsFunc: func(c echo.Context) jwt.Claims {
return new(JwtToken)
},
SigningKey: []byte("ThisIsABadSecretDontReallyUseThis"),
}
v1.POST("/login", h.AuthLogin)
v1.POST("/register", h.AuthRegister)
demo := v1.Group("/demo")
demo.GET("/hello", h.DemoHello)
demo.GET("/hello", h.DemoHello)
demo.GET("/hello/:who", h.HelloWho)
demo.Use(echojwt.WithConfig(jwtConfig))
demo.GET("/hello/body", h.HelloBody)
users := v1.Group("/users")
users.POST("/new", h.NewUser)
protected := v1.Group("/demo/protected")
protected.GET("/", h.ProtectedRoute)
//recipes := v1.Group("/recipe")
//users := v1.Group("/users")
//users.POST("/register", h.RegisterUser)
//users.POST("/login", h.LoginUser)
//users.POST("/update/password", h.UpdatePassword)
}

View File

@ -6,6 +6,10 @@ import (
"github.com/labstack/echo/v4"
)
func (h *Handler) NewUser(c echo.Context) error {
return c.JSON(http.StatusOK, "not implemented yet")
type newUserResponse struct {
}
func (h *Handler) RegisterUser(c echo.Context) error {
return c.JSON(http.StatusOK, newUserResponse{})
}