Compare commits

..

No commits in common. "8f10fbfba1d49ab6c7d994becc83e842950daa30" and "4981ef7f814500e5c6d70f9c19615bef8e282926" have entirely different histories.

21 changed files with 110 additions and 231 deletions

1
.gitignore vendored
View File

@ -10,7 +10,6 @@
*.dylib *.dylib
go-cook go-cook
*.db *.db
*.env
# Test binary, built with `go test -c` # Test binary, built with `go test -c`
*.test *.test

View File

@ -1,4 +0,0 @@
package domain
type UserDto struct {
}

View File

@ -1,21 +0,0 @@
package domain
import "time"
type UserEntity struct {
Id int
CreatedAt time.Time
LastUpdated time.Time
Name string
Hash string
Scopes string
}
type RecipeEntity struct {
Id int32
CreatedAt time.Time
LastUpdated time.Time
Title string
Thumbnail string
Content string
}

View File

@ -1,6 +0,0 @@
package domain
type EnvConfig struct {
AdminToken string
JwtSecret string
}

View File

@ -1,5 +0,0 @@
package domain
type HelloBodyRequest struct {
Name string `json:"name" validate:"required"`
}

View File

@ -1,12 +0,0 @@
package domain
type ErrorResponse struct {
HttpCode int `json:"code"`
Message string `json:"message"`
}
type HelloWhoResponse struct {
Success bool `json:"success"`
Error string `json:"error"`
Message string `json:"message"`
}

View File

@ -1,8 +0,0 @@
package domain
const (
ScopeAll = "all"
ScopeRecipeRead = "recipe:read"
ScopeRecipeCreate = "recipe:create"
ScopeRecipeDelete = "recipe:delete"
)

View File

@ -2,10 +2,9 @@ package v1
import ( import (
"errors" "errors"
"go-cook/api/domain" "go-cook/api/models"
"go-cook/api/repositories" "go-cook/api/repositories"
"net/http" "net/http"
"strings"
"time" "time"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
@ -16,57 +15,19 @@ const (
ErrJwtMissing = "auth token is missing" ErrJwtMissing = "auth token is missing"
ErrJwtClaimsMissing = "claims missing on token" ErrJwtClaimsMissing = "claims missing on token"
ErrJwtExpired = "auth token has expired" ErrJwtExpired = "auth token has expired"
ErrJwtScopeMissing = "required scope is missing"
) )
type JwtToken struct { type JwtToken struct {
Exp time.Time `json:"exp"` Exp time.Time `json:"exp"`
Iss string `json:"iss"`
Authorized bool `json:"authorized"` Authorized bool `json:"authorized"`
UserName string `json:"username"` UserName string `json:"username"`
Scopes []string `json:"scopes"` Token string `json:"token"`
jwt.RegisteredClaims jwt.RegisteredClaims
} }
func (j JwtToken) IsValid(scope string) error { func generateJwt(username string) (string, error) {
err := j.hasExpired() //TODO use env here
if err != nil { secret := []byte("ThisIsABadSecretDontReallyUseThis")
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) token := jwt.New(jwt.SigningMethodHS256)
claims := token.Claims.(jwt.MapClaims) claims := token.Claims.(jwt.MapClaims)
@ -74,10 +35,6 @@ func (h *Handler) generateJwt(username string) (string, error) {
claims["authorized"] = true claims["authorized"] = true
claims["username"] = username claims["username"] = username
var scopes []string
scopes = append(scopes, domain.ScopeRecipeRead)
claims["scopes"] = scopes
tokenString, err := token.SignedString(secret) tokenString, err := token.SignedString(secret)
if err != nil { if err != nil {
return "", err return "", err
@ -93,7 +50,7 @@ func (h *Handler) AuthRegister(c echo.Context) error {
// if we have an err, validate that if its not user not found. // 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 the user is not found, we can use that name
if err.Error() != repositories.ErrUserNotFound { if err.Error() != repositories.ErrUserNotFound {
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{ return c.JSON(http.StatusInternalServerError, models.ErrorResponse{
HttpCode: http.StatusInternalServerError, HttpCode: http.StatusInternalServerError,
Message: err.Error(), Message: err.Error(),
}) })
@ -103,7 +60,7 @@ func (h *Handler) AuthRegister(c echo.Context) error {
password := c.QueryParam("password") password := c.QueryParam("password")
err = h.UserService.CheckPasswordForRequirements(password) err = h.UserService.CheckPasswordForRequirements(password)
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{ return c.JSON(http.StatusInternalServerError, models.ErrorResponse{
HttpCode: http.StatusInternalServerError, HttpCode: http.StatusInternalServerError,
Message: err.Error(), Message: err.Error(),
}) })
@ -111,7 +68,7 @@ func (h *Handler) AuthRegister(c echo.Context) error {
_, err = h.userRepo.Create(username, password) _, err = h.userRepo.Create(username, password)
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{ return c.JSON(http.StatusInternalServerError, models.ErrorResponse{
HttpCode: http.StatusInternalServerError, HttpCode: http.StatusInternalServerError,
Message: err.Error(), Message: err.Error(),
}) })
@ -136,7 +93,7 @@ func (h *Handler) AuthLogin(c echo.Context) error {
return c.JSON(http.StatusInternalServerError, err) return c.JSON(http.StatusInternalServerError, err)
} }
token, err := h.generateJwt(username) token, err := generateJwt(username)
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, err) return c.JSON(http.StatusInternalServerError, err)
} }
@ -144,10 +101,6 @@ func (h *Handler) AuthLogin(c echo.Context) error {
return c.JSON(http.StatusOK, token) return c.JSON(http.StatusOK, token)
} }
func (h *Handler) AddScope(c echo.Context) error {
}
func (h *Handler) RefreshJwtToken(c echo.Context) error { func (h *Handler) RefreshJwtToken(c echo.Context) error {
return nil return nil
} }
@ -165,5 +118,11 @@ func (h *Handler) getJwtToken(c echo.Context) (JwtToken, error) {
return JwtToken{}, errors.New(ErrJwtClaimsMissing) return JwtToken{}, errors.New(ErrJwtClaimsMissing)
} }
// Check to see if the token has expired
hasExpired := claims.Exp.Compare(time.Now())
if hasExpired == -1 {
return JwtToken{}, errors.New(ErrJwtExpired)
}
return *claims, nil return *claims, nil
} }

View File

@ -2,14 +2,20 @@ package v1
import ( import (
"fmt" "fmt"
"go-cook/api/domain" "go-cook/api/models"
"net/http" "net/http"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
type HelloWhoResponse struct {
Success bool `json:"success"`
Error string `error:"error"`
Message string `json:"message"`
}
func (h *Handler) DemoHello(c echo.Context) error { func (h *Handler) DemoHello(c echo.Context) error {
return c.JSON(http.StatusOK, domain.HelloWhoResponse{ return c.JSON(http.StatusOK, HelloWhoResponse{
Success: true, Success: true,
Message: "Hello world!", Message: "Hello world!",
}) })
@ -17,23 +23,27 @@ func (h *Handler) DemoHello(c echo.Context) error {
func (h *Handler) HelloWho(c echo.Context) error { func (h *Handler) HelloWho(c echo.Context) error {
name := c.Param("who") name := c.Param("who")
return c.JSON(http.StatusOK, domain.HelloWhoResponse{ return c.JSON(http.StatusOK, HelloWhoResponse{
Success: true, Success: true,
Message: fmt.Sprintf("Hello, %s", name), Message: fmt.Sprintf("Hello, %s", name),
}) })
} }
type HelloBodyRequest struct {
Name string `json:"name" validate:"required"`
}
func (h *Handler) HelloBody(c echo.Context) error { func (h *Handler) HelloBody(c echo.Context) error {
request := domain.HelloBodyRequest{} request := HelloBodyRequest{}
err := (&echo.DefaultBinder{}).BindBody(c, &request) err := (&echo.DefaultBinder{}).BindBody(c, &request)
if err != nil { if err != nil {
return c.JSON(http.StatusBadRequest, domain.HelloWhoResponse{ return c.JSON(http.StatusBadRequest, HelloWhoResponse{
Success: false, Success: false,
Error: err.Error(), Error: err.Error(),
}) })
} }
return c.JSON(http.StatusOK, domain.HelloWhoResponse{ return c.JSON(http.StatusOK, HelloWhoResponse{
Success: true, Success: true,
Message: fmt.Sprintf("Hello, %s", request.Name), Message: fmt.Sprintf("Hello, %s", request.Name),
}) })
@ -42,12 +52,10 @@ func (h *Handler) HelloBody(c echo.Context) error {
func (h *Handler) ProtectedRoute(c echo.Context) error { func (h *Handler) ProtectedRoute(c echo.Context) error {
token, err := h.getJwtToken(c) token, err := h.getJwtToken(c)
if err != nil { if err != nil {
h.ReturnUnauthorizedResponse(c, err.Error()) return c.JSON(http.StatusForbidden, models.ErrorResponse{
} HttpCode: http.StatusForbidden,
Message: err.Error(),
err = token.IsValid(domain.ScopeRecipeRead) })
if err != nil {
h.ReturnUnauthorizedResponse(c, ErrJwtScopeMissing)
} }
return c.JSON(http.StatusOK, token) return c.JSON(http.StatusOK, token)

View File

@ -2,10 +2,8 @@ package v1
import ( import (
"database/sql" "database/sql"
"go-cook/api/domain"
"go-cook/api/repositories" "go-cook/api/repositories"
"go-cook/api/services" "go-cook/api/services"
"net/http"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
echojwt "github.com/labstack/echo-jwt/v4" echojwt "github.com/labstack/echo-jwt/v4"
@ -13,19 +11,16 @@ import (
) )
type Handler struct { type Handler struct {
Config domain.EnvConfig
UserService services.UserService UserService services.UserService
userRepo repositories.IUserTable userRepo repositories.IUserTable
recipeRepo repositories.IRecipeTable recipeRepo repositories.IRecipeTable
} }
func NewHandler(conn *sql.DB, cfg domain.EnvConfig) *Handler { func NewHandler(conn *sql.DB) *Handler {
return &Handler{ return &Handler{
Config: cfg,
UserService: services.NewUserService(conn), UserService: services.NewUserService(conn),
userRepo: repositories.NewUserRepository(conn), userRepo: repositories.NewUserRepository(conn),
recipeRepo: repositories.NewRecipeRepository(conn), recipeRepo: repositories.NewRecipeRepository(conn),
} }
} }
@ -34,7 +29,7 @@ func (h *Handler) Register(v1 *echo.Group) {
NewClaimsFunc: func(c echo.Context) jwt.Claims { NewClaimsFunc: func(c echo.Context) jwt.Claims {
return new(JwtToken) return new(JwtToken)
}, },
SigningKey: []byte(h.Config.JwtSecret), SigningKey: []byte("ThisIsABadSecretDontReallyUseThis"),
} }
v1.POST("/login", h.AuthLogin) v1.POST("/login", h.AuthLogin)
@ -58,10 +53,3 @@ func (h *Handler) Register(v1 *echo.Group) {
//users.POST("/login", h.LoginUser) //users.POST("/login", h.LoginUser)
//users.POST("/update/password", h.UpdatePassword) //users.POST("/update/password", h.UpdatePassword)
} }
func (h *Handler) ReturnUnauthorizedResponse(c echo.Context, message string) error {
return c.JSON(http.StatusUnauthorized, domain.ErrorResponse{
HttpCode: http.StatusUnauthorized,
Message: message,
})
}

View File

@ -1,10 +0,0 @@
-- +goose Up
-- +goose StatementBegin
SELECT 'up SQL query';
ALTER Table USERS ADD Scopes TEXT;
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
SELECT 'down SQL query';
ALTER TABLE USERS DROP COLUMN Scopes;
-- +goose StatementEnd

12
api/models/recipe.go Normal file
View File

@ -0,0 +1,12 @@
package models
import "time"
type RecipeModel struct {
Id int32
Title string
Thumbnail string
Content string
CreatedAt time.Time
LastUpdated time.Time
}

6
api/models/std.go Normal file
View File

@ -0,0 +1,6 @@
package models
type ErrorResponse struct {
HttpCode int `json:"code"`
Message string `json:"message"`
}

15
api/models/users.go Normal file
View File

@ -0,0 +1,15 @@
package models
import "time"
type UserModel struct {
Id int
Name string
Hash string
CreatedAt time.Time
LastUpdated time.Time
}
type UserDto struct {
}

View File

@ -3,15 +3,15 @@ package repositories
import ( import (
"database/sql" "database/sql"
"errors" "errors"
"go-cook/api/domain" "go-cook/api/models"
) )
type IRecipeTable interface { type IRecipeTable interface {
Create(domain.RecipeEntity) error Create(models.RecipeModel) error
List() ([]domain.RecipeEntity, error) List() ([]models.RecipeModel, error)
Get(id int) (domain.RecipeEntity, error) Get(id int) (models.RecipeModel, error)
Update(id int, entity domain.RecipeEntity) error Update(id int, entity models.RecipeModel) error
Delete(id int) error Delete(id int) error
} }
type RecipeRepository struct { type RecipeRepository struct {
@ -24,22 +24,22 @@ func NewRecipeRepository(client *sql.DB) RecipeRepository {
} }
} }
func (rr RecipeRepository) Create(domain.RecipeEntity) error { func (rr RecipeRepository) Create(models.RecipeModel) error {
return errors.New("not implemented") return errors.New("not implemented")
} }
func (rr RecipeRepository) List() ([]domain.RecipeEntity, error) { func (rr RecipeRepository) List() ([]models.RecipeModel, error) {
return []domain.RecipeEntity{}, errors.New("not implemented") return []models.RecipeModel{}, errors.New("not implemented")
} }
func (rr RecipeRepository) Get(id int) (domain.RecipeEntity, error) { func (rr RecipeRepository) Get(id int) (models.RecipeModel, error) {
return domain.RecipeEntity{}, errors.New("not implemented") return models.RecipeModel{}, errors.New("not implemented")
} }
func (rr RecipeRepository) Update(id int, entity domain.RecipeEntity) error { func (rr RecipeRepository) Update(id int, entity models.RecipeModel) error {
return errors.New("not implemented") return errors.New("not implemented")
} }
func (rr RecipeRepository) Delete(id int) error { func (rr RecipeRepository) Delete(id int) error {
return errors.New("not implemented") return errors.New("not implemented")
} }

View File

@ -4,7 +4,7 @@ import (
"database/sql" "database/sql"
"errors" "errors"
"fmt" "fmt"
"go-cook/api/domain" "go-cook/api/models"
"time" "time"
"github.com/huandu/go-sqlbuilder" "github.com/huandu/go-sqlbuilder"
@ -12,17 +12,16 @@ import (
) )
const ( const (
TableName string = "users" TableName string = "users"
ErrUserNotFound string = "requested user was not found" ErrUserNotFound string = "requested user was not found"
) )
type IUserTable interface { type IUserTable interface {
GetByName(name string) (domain.UserEntity, error) GetByName(name string) (models.UserModel, error)
Create(name, password string) (int64, error) Create(name, password string) (int64, error)
Update(id int, entity domain.UserEntity) error Update(id int, entity models.UserModel) error
UpdatePassword(name, password string) error UpdatePassword(name, password string) error
CheckUserHash(name, password string) error CheckUserHash(name, password string) error
AddScope(name, scope string) error
} }
// Creates a new instance of UserRepository with the bound sql // Creates a new instance of UserRepository with the bound sql
@ -36,7 +35,7 @@ type UserRepository struct {
connection *sql.DB connection *sql.DB
} }
func (ur UserRepository) GetByName(name string) (domain.UserEntity, error) { func (ur UserRepository) GetByName(name string) (models.UserModel, error) {
builder := sqlbuilder.NewSelectBuilder() builder := sqlbuilder.NewSelectBuilder()
builder.Select("*").From("users").Where( builder.Select("*").From("users").Where(
builder.E("Name", name), builder.E("Name", name),
@ -45,12 +44,12 @@ func (ur UserRepository) GetByName(name string) (domain.UserEntity, error) {
rows, err := ur.connection.Query(query, args...) rows, err := ur.connection.Query(query, args...)
if err != nil { if err != nil {
return domain.UserEntity{}, err return models.UserModel{}, err
} }
data := ur.processRows(rows) data := ur.processRows(rows)
if len(data) == 0 { if (len(data) == 0) {
return domain.UserEntity{}, errors.New(ErrUserNotFound) return models.UserModel{}, errors.New(ErrUserNotFound)
} }
return data[0], nil return data[0], nil
@ -78,7 +77,7 @@ func (ur UserRepository) Create(name, password string) (int64, error) {
return 1, nil return 1, nil
} }
func (ur UserRepository) Update(id int, entity domain.UserEntity) error { func (ur UserRepository) Update(id int, entity models.UserModel) error {
return errors.New("not implemented") return errors.New("not implemented")
} }
@ -110,26 +109,8 @@ func (ur UserRepository) CheckUserHash(name, password string) error {
return nil return nil
} }
func (ur UserRepository) AddScope(name, scope string) error { func (ur UserRepository) processRows(rows *sql.Rows) []models.UserModel {
builder := sqlbuilder.NewUpdateBuilder() items := []models.UserModel{}
builder.Update("users")
builder.Set (
builder.Assign("Scopes", scope),
)
builder.Where(
builder.Equal("Name", name),
)
query, args := builder.Build()
_, err := ur.connection.Exec(query, args...)
if err != nil {
return err
}
return nil
}
func (ur UserRepository) processRows(rows *sql.Rows) []domain.UserEntity {
items := []domain.UserEntity{}
for rows.Next() { for rows.Next() {
var id int var id int
@ -137,17 +118,15 @@ func (ur UserRepository) processRows(rows *sql.Rows) []domain.UserEntity {
var hash string var hash string
var createdAt time.Time var createdAt time.Time
var lastUpdated time.Time var lastUpdated time.Time
var scopes string err := rows.Scan(&id, &name, &hash, &createdAt, &lastUpdated)
err := rows.Scan(&id, &name, &hash, &createdAt, &lastUpdated, &scopes)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
items = append(items, domain.UserEntity{ items = append(items, models.UserModel{
Id: id, Id: id,
Name: name, Name: name,
Hash: hash, Hash: hash,
Scopes: scopes,
CreatedAt: createdAt, CreatedAt: createdAt,
LastUpdated: lastUpdated, LastUpdated: lastUpdated,
}) })

View File

@ -1,21 +0,0 @@
package services
import (
"go-cook/api/domain"
"log"
"os"
"github.com/joho/godotenv"
)
func NewEnvConfig() domain.EnvConfig {
err := godotenv.Load()
if err != nil {
log.Println(err)
}
return domain.EnvConfig{
AdminToken: os.Getenv("AdminToken"),
JwtSecret: os.Getenv("JwtSecret"),
}
}

View File

@ -3,7 +3,7 @@ package services
import ( import (
"database/sql" "database/sql"
"errors" "errors"
"go-cook/api/domain" "go-cook/api/models"
"go-cook/api/repositories" "go-cook/api/repositories"
"strings" "strings"
@ -36,6 +36,12 @@ func (us UserService) DoesUserExist(username string) error {
} }
func (us UserService) DoesPasswordMatchHash(username, password string) error { func (us UserService) DoesPasswordMatchHash(username, password string) error {
//passwordBytes := []byte(password)
//hash, err := bcrypt.GenerateFromPassword(passwordBytes, bcrypt.DefaultCost)
//if err != nil {
// return err
//}
model, err := us.GetUser(username) model, err := us.GetUser(username)
if err != nil { if err != nil {
return err return err
@ -49,18 +55,18 @@ func (us UserService) DoesPasswordMatchHash(username, password string) error {
return nil return nil
} }
func (us UserService) GetUser(username string) (domain.UserEntity, error) { func (us UserService) GetUser(username string) (models.UserModel, error) {
return us.repo.GetByName(username) return us.repo.GetByName(username)
} }
func (us UserService) CreateNewUser(name, password string) (domain.UserEntity, error) { func (us UserService) CreateNewUser(name, password string) (models.UserModel, error) {
err := us.CheckPasswordForRequirements(password) err := us.CheckPasswordForRequirements(password)
if err != nil { if err != nil {
return domain.UserEntity{}, err return models.UserModel{}, err
} }
us.repo.Create(name, password) us.repo.Create(name, password)
return domain.UserEntity{}, nil return models.UserModel{}, nil
} }
func (us UserService) CheckPasswordForRequirements(password string) error { func (us UserService) CheckPasswordForRequirements(password string) error {

1
go.mod
View File

@ -25,7 +25,6 @@ require (
github.com/google/uuid v1.5.0 // indirect github.com/google/uuid v1.5.0 // indirect
github.com/huandu/go-sqlbuilder v1.25.0 // indirect github.com/huandu/go-sqlbuilder v1.25.0 // indirect
github.com/huandu/xstrings v1.3.2 // indirect github.com/huandu/xstrings v1.3.2 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/labstack/echo-jwt/v4 v4.2.0 // indirect github.com/labstack/echo-jwt/v4 v4.2.0 // indirect
github.com/labstack/echo/v4 v4.11.4 // indirect github.com/labstack/echo/v4 v4.11.4 // indirect

2
go.sum
View File

@ -43,8 +43,6 @@ github.com/huandu/go-sqlbuilder v1.25.0 h1:h1l+6CqeCviPJCnkEZoRGNdfZ5RO9BKMvG3A+
github.com/huandu/go-sqlbuilder v1.25.0/go.mod h1:nUVmMitjOmn/zacMLXT0d3Yd3RHoO2K+vy906JzqxMI= github.com/huandu/go-sqlbuilder v1.25.0/go.mod h1:nUVmMitjOmn/zacMLXT0d3Yd3RHoO2K+vy906JzqxMI=
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=

View File

@ -3,7 +3,6 @@ package main
import ( import (
"database/sql" "database/sql"
v1 "go-cook/api/handlers/v1" v1 "go-cook/api/handlers/v1"
"go-cook/api/services"
"log" "log"
"net/http" "net/http"
@ -22,8 +21,6 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
cfg := services.NewEnvConfig()
e := echo.New() e := echo.New()
e.Validator = &CustomValidator{ e.Validator = &CustomValidator{
validator: validator.New(), validator: validator.New(),
@ -33,7 +30,7 @@ func main() {
e.Pre(middleware.Recover()) e.Pre(middleware.Recover())
v1Group := e.Group("/api/v1") v1Group := e.Group("/api/v1")
v1Api := v1.NewHandler(db, cfg) v1Api := v1.NewHandler(db)
v1Api.Register(v1Group) v1Api.Register(v1Group)
e.Logger.Fatal(e.Start(":1323")) e.Logger.Fatal(e.Start(":1323"))