Continue migration to echo

This commit is contained in:
Jan Bader 2022-08-20 22:44:59 +00:00
parent 1a11555075
commit 9da4a6f03e
10 changed files with 76 additions and 99 deletions

8
go.mod
View File

@ -11,15 +11,19 @@ require (
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa
) )
require github.com/DATA-DOG/go-txdb v0.1.5 require (
github.com/DATA-DOG/go-txdb v0.1.5
github.com/labstack/echo/v4 v4.8.0
)
require ( require (
github.com/labstack/echo/v4 v4.8.0 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/labstack/gommon v0.3.1 // indirect github.com/labstack/gommon v0.3.1 // indirect
github.com/mattn/go-colorable v0.1.11 // indirect github.com/mattn/go-colorable v0.1.11 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect github.com/valyala/fasttemplate v1.2.1 // indirect
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect
) )
require ( require (

9
go.sum
View File

@ -83,6 +83,8 @@ github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@ -206,7 +208,6 @@ github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHR
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
@ -334,6 +335,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa h1:idItI2DDfCokpg0N51B2VtiLdJ4vAuXC9fnCb2gACo4= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa h1:idItI2DDfCokpg0N51B2VtiLdJ4vAuXC9fnCb2gACo4=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -389,7 +391,6 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -401,11 +402,12 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -453,7 +455,6 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -12,22 +12,19 @@ type newBudgetInformation struct {
func (h *Handler) newBudget(c echo.Context) error { func (h *Handler) newBudget(c echo.Context) error {
var newBudget newBudgetInformation var newBudget newBudgetInformation
if err := c.BindJSON(&newBudget); err != nil { if err := c.Bind(&newBudget); err != nil {
return echo.NewHTTPError(http.StatusNotAcceptable, err) return echo.NewHTTPError(http.StatusNotAcceptable, err)
return
} }
if newBudget.Name == "" { if newBudget.Name == "" {
c.AbortWithStatusJSON(http.StatusBadRequest, ErrorResponse{"budget name is required"}) return echo.NewHTTPError(http.StatusBadRequest, "budget name is required")
return
} }
userID := MustGetToken(c).GetID() userID := MustGetToken(c).GetID()
budget, err := h.Service.NewBudget(c.Request().Context(), newBudget.Name, userID) budget, err := h.Service.NewBudget(c.Request().Context(), newBudget.Name, userID)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return err
return
} }
c.JSON(http.StatusOK, budget) return c.JSON(http.StatusOK, budget)
} }

View File

@ -31,28 +31,25 @@ func (h *Handler) budgetingForMonth(c echo.Context) error {
budgetID := c.Param("budgetid") budgetID := c.Param("budgetid")
budgetUUID, err := uuid.Parse(budgetID) budgetUUID, err := uuid.Parse(budgetID)
if err != nil { if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, ErrorResponse{"budgetid missing from URL"}) return echo.NewHTTPError(http.StatusBadRequest, "budgetid missing from URL")
return
} }
budget, err := h.Service.GetBudget(c.Request().Context(), budgetUUID) budget, err := h.Service.GetBudget(c.Request().Context(), budgetUUID)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err) return echo.NewHTTPError(http.StatusBadRequest, err)
return
} }
month, err := getDate(c) month, err := getDate(c)
if err != nil { if err != nil {
c.Redirect(http.StatusTemporaryRedirect, "/budget/"+budget.ID.String()) c.Redirect(http.StatusTemporaryRedirect, "/budget/"+budget.ID.String())
return
} }
data, err := h.getBudgetingViewForMonth(c.Request().Context(), budget, month) data, err := h.getBudgetingViewForMonth(c.Request().Context(), budget, month)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return err
return
} }
c.JSON(http.StatusOK, data)
return c.JSON(http.StatusOK, data)
} }
func (h *Handler) getBudgetingViewForMonth(ctx context.Context, budget postgres.Budget, month Month) (BudgetingForMonthResponse, error) { func (h *Handler) getBudgetingViewForMonth(ctx context.Context, budget postgres.Budget, month Month) (BudgetingForMonthResponse, error) {

View File

@ -18,28 +18,24 @@ func (h *Handler) setCategoryAssignment(c echo.Context) error {
categoryID := c.Param("categoryid") categoryID := c.Param("categoryid")
categoryUUID, err := uuid.Parse(categoryID) categoryUUID, err := uuid.Parse(categoryID)
if err != nil { if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, ErrorResponse{"categoryid missing from URL"}) return echo.NewHTTPError(http.StatusBadRequest, "categoryid missing from URL")
return
} }
var request SetCategoryAssignmentRequest var request SetCategoryAssignmentRequest
err = c.BindJSON(&request) err = c.Bind(&request)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Errorf("invalid payload: %w", err)) return echo.NewHTTPError(http.StatusBadRequest, fmt.Errorf("invalid payload: %w", err))
return
} }
date, err := getDate(c) date, err := getDate(c)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Errorf("date invalid: %w", err)) return echo.NewHTTPError(http.StatusBadRequest, fmt.Errorf("date invalid: %w", err))
return
} }
var amount numeric.Numeric var amount numeric.Numeric
err = amount.Set(request.Assigned) err = amount.Set(request.Assigned)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Errorf("parse amount: %w", err)) return echo.NewHTTPError(http.StatusBadRequest, fmt.Errorf("parse amount: %w", err))
return
} }
updateArgs := postgres.UpdateAssignmentParams{ updateArgs := postgres.UpdateAssignmentParams{
@ -49,7 +45,8 @@ func (h *Handler) setCategoryAssignment(c echo.Context) error {
} }
err = h.Service.UpdateAssignment(c.Request().Context(), updateArgs) err = h.Service.UpdateAssignment(c.Request().Context(), updateArgs)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("update assignment: %w", err)) return fmt.Errorf("update assignment: %w", err)
return
} }
return nil
} }

View File

@ -13,6 +13,7 @@ import (
"git.javil.eu/jacob1123/budgeteer/postgres" "git.javil.eu/jacob1123/budgeteer/postgres"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
) )
// Handler handles incoming requests. // Handler handles incoming requests.
@ -36,7 +37,10 @@ func (h *Handler) Serve() {
// LoadRoutes initializes all the routes. // LoadRoutes initializes all the routes.
func (h *Handler) LoadRoutes(router *echo.Echo) { func (h *Handler) LoadRoutes(router *echo.Echo) {
router.Use(enableCachingForStaticFiles()) router.Use(enableCachingForStaticFiles())
router.Use(h.ServeStatic) router.Use(middleware.StaticWithConfig(middleware.StaticConfig{
Filesystem: h.StaticFS,
HTML5: true,
}))
api := router.Group("/api/v1") api := router.Group("/api/v1")

View File

@ -7,7 +7,6 @@ import (
"git.javil.eu/jacob1123/budgeteer" "git.javil.eu/jacob1123/budgeteer"
"git.javil.eu/jacob1123/budgeteer/postgres" "git.javil.eu/jacob1123/budgeteer/postgres"
"github.com/gin-gonic/gin"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
@ -18,8 +17,8 @@ const (
ParamName = "token" ParamName = "token"
) )
func MustGetToken(c *gin.Context) budgeteer.Token { //nolint:ireturn func MustGetToken(c echo.Context) budgeteer.Token { //nolint:ireturn
token := c.MustGet(ParamName) token := c.Get(ParamName)
if token, ok := token.(budgeteer.Token); ok { if token, ok := token.(budgeteer.Token); ok {
return token return token
} }
@ -27,16 +26,16 @@ func MustGetToken(c *gin.Context) budgeteer.Token { //nolint:ireturn
panic("Token is not a valid Token") panic("Token is not a valid Token")
} }
func (h *Handler) verifyLogin(c echo.Context) (budgeteer.Token, *ErrorResponse) { //nolint:ireturn func (h *Handler) verifyLogin(c echo.Context) (budgeteer.Token, error) { //nolint:ireturn
tokenString := c.Request().Header.Get(HeaderName) tokenString := c.Request().Header.Get(HeaderName)
if len(tokenString) <= len(Bearer) { if len(tokenString) <= len(Bearer) {
return nil, &ErrorResponse{"no authorization header supplied"} return nil, echo.NewHTTPError(http.StatusUnauthorized, "no authorization header supplied")
} }
tokenString = tokenString[7:] tokenString = tokenString[7:]
token, err := h.TokenVerifier.VerifyToken(tokenString) token, err := h.TokenVerifier.VerifyToken(tokenString)
if err != nil { if err != nil {
return nil, &ErrorResponse{fmt.Sprintf("verify token '%s': %s", tokenString, err)} return nil, fmt.Errorf("verify token '%s': %s", tokenString, err)
} }
return token, nil return token, nil
@ -107,16 +106,16 @@ func (h *Handler) registerPost(c echo.Context) error {
var register registerInformation var register registerInformation
err := c.Bind(&register) err := c.Bind(&register)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, ErrorResponse{"error parsing body"}) return echo.NewHTTPError(http.StatusBadRequest, "error parsing body")
} }
if register.Email == "" || register.Password == "" || register.Name == "" { if register.Email == "" || register.Password == "" || register.Name == "" {
return echo.NewHTTPError(http.StatusBadRequest, ErrorResponse{"e-mail, password and name are required"}) return echo.NewHTTPError(http.StatusBadRequest, "e-mail, password and name are required")
} }
_, err = h.Service.GetUserByUsername(c.Request().Context(), register.Email) _, err = h.Service.GetUserByUsername(c.Request().Context(), register.Email)
if err == nil { if err == nil {
return echo.NewHTTPError(http.StatusBadRequest, ErrorResponse{"email is already taken"}) return echo.NewHTTPError(http.StatusBadRequest, "email is already taken")
} }
hash, err := h.CredentialsVerifier.Hash(register.Password) hash, err := h.CredentialsVerifier.Hash(register.Password)

View File

@ -8,7 +8,6 @@ import (
"git.javil.eu/jacob1123/budgeteer/postgres" "git.javil.eu/jacob1123/budgeteer/postgres"
"git.javil.eu/jacob1123/budgeteer/postgres/numeric" "git.javil.eu/jacob1123/budgeteer/postgres/numeric"
"github.com/gin-gonic/gin"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
@ -30,40 +29,35 @@ type NewTransactionPayload struct {
func (h *Handler) updateTransaction(c echo.Context) error { func (h *Handler) updateTransaction(c echo.Context) error {
var payload NewTransactionPayload var payload NewTransactionPayload
err := c.BindJSON(&payload) err := c.Bind(&payload)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err) return echo.NewHTTPError(http.StatusBadRequest, err)
return
} }
amount, err := numeric.Parse(payload.Amount) amount, err := numeric.Parse(payload.Amount)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Errorf("amount: %w", err)) return echo.NewHTTPError(http.StatusBadRequest, fmt.Errorf("amount: %w", err))
return
} }
transactionID := c.Param("transactionid") transactionID := c.Param("transactionid")
transactionUUID, err := uuid.Parse(transactionID) transactionUUID, err := uuid.Parse(transactionID)
if err != nil { if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, ErrorResponse{"transactionid missing from URL"}) return echo.NewHTTPError(http.StatusBadRequest, "transactionid missing from URL")
return
} }
h.UpdateTransaction(payload, amount, transactionUUID, c) return h.UpdateTransaction(payload, amount, transactionUUID, c)
} }
func (h *Handler) newTransaction(c echo.Context) error { func (h *Handler) newTransaction(c echo.Context) error {
var payload NewTransactionPayload var payload NewTransactionPayload
err := c.BindJSON(&payload) err := c.Bind(&payload)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err) return echo.NewHTTPError(http.StatusBadRequest, err)
return
} }
amount, err := numeric.Parse(payload.Amount) amount, err := numeric.Parse(payload.Amount)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Errorf("amount: %w", err)) return echo.NewHTTPError(http.StatusBadRequest, fmt.Errorf("amount: %w", err))
return
} }
newTransaction := postgres.CreateTransactionParams{ newTransaction := postgres.CreateTransactionParams{
@ -79,7 +73,6 @@ func (h *Handler) newTransaction(c echo.Context) error {
groupID, err := h.CreateTransferForOtherAccount(newTransaction, amount, payload, c) groupID, err := h.CreateTransferForOtherAccount(newTransaction, amount, payload, c)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return echo.NewHTTPError(http.StatusInternalServerError, err)
return
} }
newTransaction.GroupID = groupID newTransaction.GroupID = groupID
@ -94,16 +87,14 @@ func (h *Handler) newTransaction(c echo.Context) error {
transactionUUID, err := h.Service.CreateTransaction(c.Request().Context(), newTransaction) transactionUUID, err := h.Service.CreateTransaction(c.Request().Context(), newTransaction)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("create transaction: %w", err)) return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("create transaction: %w", err))
return
} }
transaction, err := h.Service.GetTransaction(c.Request().Context(), transactionUUID) transaction, err := h.Service.GetTransaction(c.Request().Context(), transactionUUID)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("get transaction: %w", err)) return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("get transaction: %w", err))
return
} }
c.JSON(http.StatusOK, transaction) return c.JSON(http.StatusOK, transaction)
} }
func (h *Handler) UpdateTransaction(payload NewTransactionPayload, amount numeric.Numeric, transactionUUID uuid.UUID, c echo.Context) error { func (h *Handler) UpdateTransaction(payload NewTransactionPayload, amount numeric.Numeric, transactionUUID uuid.UUID, c echo.Context) error {
@ -112,7 +103,7 @@ func (h *Handler) UpdateTransaction(payload NewTransactionPayload, amount numeri
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("delete transaction: %w", err)) return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("delete transaction: %w", err))
} }
return return nil
} }
editTransaction := postgres.UpdateTransactionParams{ editTransaction := postgres.UpdateTransactionParams{
@ -127,19 +118,17 @@ func (h *Handler) UpdateTransaction(payload NewTransactionPayload, amount numeri
err := h.Service.UpdateTransaction(c.Request().Context(), editTransaction) err := h.Service.UpdateTransaction(c.Request().Context(), editTransaction)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("edit transaction: %w", err)) return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("edit transaction: %w", err))
return
} }
transaction, err := h.Service.GetTransaction(c.Request().Context(), transactionUUID) transaction, err := h.Service.GetTransaction(c.Request().Context(), transactionUUID)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("get transaction: %w", err)) return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("get transaction: %w", err))
return
} }
c.JSON(http.StatusOK, transaction) return c.JSON(http.StatusOK, transaction)
} }
func (h *Handler) CreateTransferForOtherAccount(newTransaction postgres.CreateTransactionParams, amount numeric.Numeric, payload NewTransactionPayload, c *gin.Context) (uuid.NullUUID, error) { func (h *Handler) CreateTransferForOtherAccount(newTransaction postgres.CreateTransactionParams, amount numeric.Numeric, payload NewTransactionPayload, c echo.Context) (uuid.NullUUID, error) {
newTransaction.GroupID = uuid.NullUUID{UUID: uuid.New(), Valid: true} newTransaction.GroupID = uuid.NullUUID{UUID: uuid.New(), Valid: true}
newTransaction.Amount = amount.Neg() newTransaction.Amount = amount.Neg()
newTransaction.AccountID = payload.Payee.ID.UUID newTransaction.AccountID = payload.Payee.ID.UUID

View File

@ -5,10 +5,10 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/gin-gonic/gin" "github.com/labstack/echo/v4"
) )
func getDate(c *gin.Context) (Month, error) { func getDate(c echo.Context) (Month, error) {
var year, month int var year, month int
yearString := c.Param("year") yearString := c.Param("year")
monthString := c.Param("month") monthString := c.Param("month")

View File

@ -9,109 +9,98 @@ import (
) )
func (h *Handler) importYNAB(c echo.Context) error { func (h *Handler) importYNAB(c echo.Context) error {
budgetID, succ := c.Params.Get("budgetid") budgetID := c.Param("budgetid")
if !succ { if budgetID == "" {
c.AbortWithStatusJSON(http.StatusBadRequest, ErrorResponse{"no budget_id specified"}) return echo.NewHTTPError(http.StatusBadRequest, "no budget_id specified")
return
} }
budgetUUID, err := uuid.Parse(budgetID) budgetUUID, err := uuid.Parse(budgetID)
if !succ { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err) return echo.NewHTTPError(http.StatusBadRequest, err)
return
} }
ynab, err := postgres.NewYNABImport(c.Request().Context(), h.Service.Queries, budgetUUID) ynab, err := postgres.NewYNABImport(c.Request().Context(), h.Service.Queries, budgetUUID)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return err
return
} }
transactionsFile, err := c.FormFile("transactions") transactionsFile, err := c.FormFile("transactions")
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return err
return
} }
transactions, err := transactionsFile.Open() transactions, err := transactionsFile.Open()
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return err
return
} }
err = ynab.ImportTransactions(c.Request().Context(), transactions) err = ynab.ImportTransactions(c.Request().Context(), transactions)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return err
return
} }
assignmentsFile, err := c.FormFile("assignments") assignmentsFile, err := c.FormFile("assignments")
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return err
return
} }
assignments, err := assignmentsFile.Open() assignments, err := assignmentsFile.Open()
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return err
return
} }
err = ynab.ImportAssignments(c.Request().Context(), assignments) err = ynab.ImportAssignments(c.Request().Context(), assignments)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return err
return
} }
return nil
} }
func (h *Handler) exportYNABTransactions(c echo.Context) error { func (h *Handler) exportYNABTransactions(c echo.Context) error {
budgetID, succ := c.Params.Get("budgetid") budgetID := c.Param("budgetid")
if !succ { if budgetID == "" {
c.AbortWithStatusJSON(http.StatusBadRequest, ErrorResponse{"no budget_id specified"}) return echo.NewHTTPError(http.StatusBadRequest, "no budget_id specified")
return
} }
budgetUUID, err := uuid.Parse(budgetID) budgetUUID, err := uuid.Parse(budgetID)
if !succ { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err) return echo.NewHTTPError(http.StatusBadRequest, err)
return
} }
ynab, err := postgres.NewYNABExport(c.Request().Context(), h.Service.Queries, budgetUUID) ynab, err := postgres.NewYNABExport(c.Request().Context(), h.Service.Queries, budgetUUID)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return err
return
} }
err = ynab.ExportTransactions(c.Request().Context(), c.Writer) err = ynab.ExportTransactions(c.Request().Context(), c.Response().Writer)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return err
return
} }
return nil
} }
func (h *Handler) exportYNABAssignments(c echo.Context) error { func (h *Handler) exportYNABAssignments(c echo.Context) error {
budgetID, succ := c.Params.Get("budgetid") budgetID := c.Param("budgetid")
if !succ { if budgetID == "" {
c.AbortWithStatusJSON(http.StatusBadRequest, ErrorResponse{"no budget_id specified"}) return echo.NewHTTPError(http.StatusBadRequest, "no budget_id specified")
return
} }
budgetUUID, err := uuid.Parse(budgetID) budgetUUID, err := uuid.Parse(budgetID)
if !succ { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err) return echo.NewHTTPError(http.StatusBadRequest, err)
return
} }
ynab, err := postgres.NewYNABExport(c.Request().Context(), h.Service.Queries, budgetUUID) ynab, err := postgres.NewYNABExport(c.Request().Context(), h.Service.Queries, budgetUUID)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return echo.NewHTTPError(http.StatusInternalServerError, err)
return
} }
err = ynab.ExportAssignments(c.Request().Context(), c.Writer) err = ynab.ExportAssignments(c.Request().Context(), c.Response().Writer)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err) return echo.NewHTTPError(http.StatusInternalServerError, err)
return
} }
return nil
} }