Skip to content

Commit

Permalink
fix: inaccruate 401 & sql busy error (#679)
Browse files Browse the repository at this point in the history
* fix inaccruate 401 error on SQL db error

* init golangci-lint config

* linter autofix

* testify auto fixes

* fix sqlite busy errors

* fix naming

* more linter errors

* fix rest of linter issues
  • Loading branch information
hay-kot committed Jan 4, 2024
1 parent b918310 commit e8449b3
Show file tree
Hide file tree
Showing 62 changed files with 392 additions and 295 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"editor.formatOnSave": false,
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ FROM alpine:latest

ENV HBOX_MODE=production
ENV HBOX_STORAGE_DATA=/data/
ENV HBOX_STORAGE_SQLITE_URL=/data/homebox.db?_fk=1
ENV HBOX_STORAGE_SQLITE_URL=/data/homebox.db?_pragma=busy_timeout=2000&_pragma=journal_mode=WAL&_fk=1

RUN apk --no-cache add ca-certificates
RUN mkdir /app
Expand Down
73 changes: 73 additions & 0 deletions backend/.golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
run:
timeout: 10m
skip-dirs:
- internal/data/ent.*
linters-settings:
goconst:
min-len: 5
min-occurrences: 5
exhaustive:
default-signifies-exhaustive: true
revive:
ignore-generated-header: false
severity: warning
confidence: 3
depguard:
rules:
main:
deny:
- pkg: io/util
desc: |
Deprecated: As of Go 1.16, the same functionality is now provided by
package io or package os, and those implementations should be
preferred in new code. See the specific function documentation for
details.
gocritic:
enabled-checks:
- ruleguard
testifylint:
enable-all: true
tagalign:
order:
- json
- schema
- yaml
- yml
- toml
- validate
linters:
disable-all: true
enable:
- asciicheck
- bodyclose
- depguard
- dogsled
- errcheck
- errorlint
- exhaustive
- exportloopref
- gochecknoinits
- goconst
- gocritic
- gocyclo
- goprintffuncname
- gosimple
- govet
- ineffassign
- misspell
- nakedret
- revive
- staticcheck
- stylecheck
- tagalign
- testifylint
- typecheck
- typecheck
- unconvert
- unused
- whitespace
- zerologlint
- sqlclosecheck
issues:
exclude-use-default: false
fix: true
2 changes: 1 addition & 1 deletion backend/app/api/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (a *app) SetupDemo() {
,Office,IOT;Home Assistant; Z-Wave,1,Zooz 110v Power Switch,"Zooz Z-Wave Plus Power Switch ZEN15 for 110V AC Units, Sump Pumps, Humidifiers, and More",,,ZEN15,Zooz,,Amazon,39.95,10/13/2021,,,,,,,
,Downstairs,IOT;Home Assistant; Z-Wave,1,Ecolink Z-Wave PIR Motion Sensor,"Ecolink Z-Wave PIR Motion Detector Pet Immune, White (PIRZWAVE2.5-ECO)",,,PIRZWAVE2.5-ECO,Ecolink,,Amazon,35.58,10/21/2020,,,,,,,
,Entry,IOT;Home Assistant; Z-Wave,1,Yale Security Touchscreen Deadbolt,"Yale Security YRD226-ZW2-619 YRD226ZW2619 Touchscreen Deadbolt, Satin Nickel",,,YRD226ZW2619,Yale,,Amazon,120.39,10/14/2020,,,,,,,
,Kitchen,IOT;Home Assistant; Z-Wave,1,Smart Rocker Light Dimmer,"UltraPro Z-Wave Smart Rocker Light Dimmer with QuickFit and SimpleWire, 3-Way Ready, Compatible with Alexa, Google Assistant, ZWave Hub Required, Repeater/Range Extender, White Paddle Only, 39351",,,39351,Honeywell,,Amazon,65.98,09/30/0202,,,,,,,
,Kitchen,IOT;Home Assistant; Z-Wave,1,Smart Rocker Light Dimmer,"UltraPro Z-Wave Smart Rocker Light Dimmer with QuickFit and SimpleWire, 3-Way Ready, Compatible with Alexa, Google Assistant, ZWave Hub Required, Repeater/Range Extender, White Paddle Only, 39351",,,39351,Honeywell,,Amazon,65.98,09/30/0202,,,,,,,
`

registration := services.UserRegistration{
Expand Down
1 change: 1 addition & 0 deletions backend/app/api/handlers/debughandlers/debug.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package debughandlers provides handlers for debugging.
package debughandlers

import (
Expand Down
7 changes: 4 additions & 3 deletions backend/app/api/handlers/v1/controller.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package v1 provides the API handlers for version 1 of the API.
package v1

import (
Expand Down Expand Up @@ -74,7 +75,7 @@ type (
BuildTime string `json:"buildTime"`
}

ApiSummary struct {
APISummary struct {
Healthy bool `json:"health"`
Versions []string `json:"versions"`
Title string `json:"title"`
Expand All @@ -85,7 +86,7 @@ type (
}
)

func BaseUrlFunc(prefix string) func(s string) string {
func BaseURLFunc(prefix string) func(s string) string {
return func(s string) string {
return prefix + "/v1" + s
}
Expand Down Expand Up @@ -115,7 +116,7 @@ func NewControllerV1(svc *services.AllServices, repos *repo.AllRepos, bus *event
// @Router /v1/status [GET]
func (ctrl *V1Controller) HandleBase(ready ReadyFunc, build Build) errchain.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) error {
return server.JSON(w, http.StatusOK, ApiSummary{
return server.JSON(w, http.StatusOK, APISummary{
Healthy: ready(),
Title: "Homebox",
Message: "Track, Manage, and Organize your Things",
Expand Down
8 changes: 4 additions & 4 deletions backend/app/api/handlers/v1/v1_ctrl_assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ import (
func (ctrl *V1Controller) HandleAssetGet() errchain.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) error {
ctx := services.NewContext(r.Context())
assetIdParam := chi.URLParam(r, "id")
assetIdParam = strings.ReplaceAll(assetIdParam, "-", "") // Remove dashes
assetIDParam := chi.URLParam(r, "id")
assetIDParam = strings.ReplaceAll(assetIDParam, "-", "") // Remove dashes
// Convert the asset ID to an int64
assetId, err := strconv.ParseInt(assetIdParam, 10, 64)
assetID, err := strconv.ParseInt(assetIDParam, 10, 64)
if err != nil {
return err
}
Expand All @@ -52,7 +52,7 @@ func (ctrl *V1Controller) HandleAssetGet() errchain.HandlerFunc {
}
}

items, err := ctrl.repo.Items.QueryByAssetID(r.Context(), ctx.GID, repo.AssetID(assetId), int(page), int(pageSize))
items, err := ctrl.repo.Items.QueryByAssetID(r.Context(), ctx.GID, repo.AssetID(assetID), int(page), int(pageSize))
if err != nil {
log.Err(err).Msg("failed to get item")
return validate.NewRequestError(err, http.StatusInternalServerError)
Expand Down
2 changes: 1 addition & 1 deletion backend/app/api/handlers/v1/v1_ctrl_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func (ctrl *V1Controller) HandleAuthLogout() errchain.HandlerFunc {
}
}

// HandleAuthLogout godoc
// HandleAuthRefresh godoc
//
// @Summary User Token Refresh
// @Description handleAuthRefresh returns a handler that will issue a new token from an existing token.
Expand Down
2 changes: 1 addition & 1 deletion backend/app/api/handlers/v1/v1_ctrl_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (

type (
GroupInvitationCreate struct {
Uses int `json:"uses" validate:"required,min=1,max=100"`
Uses int `json:"uses" validate:"required,min=1,max=100"`
ExpiresAt time.Time `json:"expiresAt"`
}

Expand Down
1 change: 0 additions & 1 deletion backend/app/api/handlers/v1/v1_ctrl_items.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ func (ctrl *V1Controller) HandleGetAllCustomFieldValues() errchain.HandlerFunc {
}

return adapters.Query(fn, http.StatusOK)

}

// HandleItemsImport godocs
Expand Down
1 change: 0 additions & 1 deletion backend/app/api/handlers/v1/v1_ctrl_items_attachments.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ func (ctrl *V1Controller) HandleItemAttachmentCreate() errchain.HandlerFunc {
if err != nil {
log.Err(err).Msg("failed to parse multipart form")
return validate.NewRequestError(errors.New("failed to parse multipart form"), http.StatusBadRequest)

}

errs := validate.NewFieldErrors()
Expand Down
12 changes: 6 additions & 6 deletions backend/app/api/handlers/v1/v1_ctrl_locations.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/hay-kot/httpkit/errchain"
)

// HandleLocationTreeQuery
// HandleLocationTreeQuery godoc
//
// @Summary Get Locations Tree
// @Tags Locations
Expand All @@ -28,7 +28,7 @@ func (ctrl *V1Controller) HandleLocationTreeQuery() errchain.HandlerFunc {
return adapters.Query(fn, http.StatusOK)
}

// HandleLocationGetAll
// HandleLocationGetAll godoc
//
// @Summary Get All Locations
// @Tags Locations
Expand All @@ -46,7 +46,7 @@ func (ctrl *V1Controller) HandleLocationGetAll() errchain.HandlerFunc {
return adapters.Query(fn, http.StatusOK)
}

// HandleLocationCreate
// HandleLocationCreate godoc
//
// @Summary Create Location
// @Tags Locations
Expand All @@ -64,7 +64,7 @@ func (ctrl *V1Controller) HandleLocationCreate() errchain.HandlerFunc {
return adapters.Action(fn, http.StatusCreated)
}

// HandleLocationDelete
// HandleLocationDelete godoc
//
// @Summary Delete Location
// @Tags Locations
Expand All @@ -83,7 +83,7 @@ func (ctrl *V1Controller) HandleLocationDelete() errchain.HandlerFunc {
return adapters.CommandID("id", fn, http.StatusNoContent)
}

// HandleLocationGet
// HandleLocationGet godoc
//
// @Summary Get Location
// @Tags Locations
Expand All @@ -101,7 +101,7 @@ func (ctrl *V1Controller) HandleLocationGet() errchain.HandlerFunc {
return adapters.CommandID("id", fn, http.StatusOK)
}

// HandleLocationUpdate
// HandleLocationUpdate godoc
//
// @Summary Update Location
// @Tags Locations
Expand Down
2 changes: 1 addition & 1 deletion backend/app/api/handlers/v1/v1_ctrl_maint_entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/hay-kot/httpkit/errchain"
)

// HandleMaintenanceGetLog godoc
// HandleMaintenanceLogGet godoc
//
// @Summary Get Maintenance Log
// @Tags Maintenance
Expand Down
2 changes: 1 addition & 1 deletion backend/app/api/handlers/v1/v1_ctrl_statistics.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/hay-kot/httpkit/server"
)

// HandleGroupGet godoc
// HandleGroupStatisticsLocations godoc
//
// @Summary Get Location Statistics
// @Tags Statistics
Expand Down
6 changes: 3 additions & 3 deletions backend/app/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ func run(cfg *config.Config) error {
log.Fatal().Err(err).Msg("failed to create data directory")
}

c, err := ent.Open("sqlite3", cfg.Storage.SqliteUrl)
c, err := ent.Open("sqlite3", cfg.Storage.SqliteURL)
if err != nil {
log.Fatal().
Err(err).
Str("driver", "sqlite").
Str("url", cfg.Storage.SqliteUrl).
Str("url", cfg.Storage.SqliteURL).
Msg("failed opening connection to sqlite")
}
defer func(c *ent.Client) {
Expand Down Expand Up @@ -116,7 +116,7 @@ func run(cfg *config.Config) error {
log.Fatal().
Err(err).
Str("driver", "sqlite").
Str("url", cfg.Storage.SqliteUrl).
Str("url", cfg.Storage.SqliteURL).
Msg("failed creating schema resources")
}

Expand Down
9 changes: 7 additions & 2 deletions backend/app/api/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

v1 "github.com/hay-kot/homebox/backend/app/api/handlers/v1"
"github.com/hay-kot/homebox/backend/internal/core/services"
"github.com/hay-kot/homebox/backend/internal/data/ent"
"github.com/hay-kot/homebox/backend/internal/sys/validate"
"github.com/hay-kot/httpkit/errchain"
)
Expand Down Expand Up @@ -130,7 +131,7 @@ func (a *app) mwAuthToken(next errchain.Handler) errchain.Handler {
}

if requestToken == "" {
return validate.NewRequestError(errors.New("Authorization header or query is required"), http.StatusUnauthorized)
return validate.NewRequestError(errors.New("authorization header or query is required"), http.StatusUnauthorized)
}

requestToken = strings.TrimPrefix(requestToken, "Bearer ")
Expand All @@ -140,7 +141,11 @@ func (a *app) mwAuthToken(next errchain.Handler) errchain.Handler {
usr, err := a.services.User.GetSelf(r.Context(), requestToken)
// Check the database for the token
if err != nil {
return validate.NewRequestError(errors.New("valid authorization header is required"), http.StatusUnauthorized)
if ent.IsNotFound(err) {
return validate.NewRequestError(errors.New("valid authorization token is required"), http.StatusUnauthorized)
}

return err
}

r = r.WithContext(services.SetUserCtx(r.Context(), &usr, requestToken))
Expand Down
2 changes: 2 additions & 0 deletions backend/app/api/providers/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package providers provides a authentication abstraction for the backend.
package providers
4 changes: 2 additions & 2 deletions backend/app/api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllR
// =========================================================================
// API Version 1

v1Base := v1.BaseUrlFunc(prefix)
v1Base := v1.BaseURLFunc(prefix)

v1Ctrl := v1.NewControllerV1(
a.services,
Expand Down Expand Up @@ -183,7 +183,7 @@ func notFoundHandler() errchain.HandlerFunc {
if err != nil {
return err
}
defer f.Close()
defer func() { _ = f.Close() }()

stat, _ := f.Stat()
if stat.IsDir() {
Expand Down
1 change: 1 addition & 0 deletions backend/internal/core/services/all.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package services provides the core business logic for the application.
package services

import (
Expand Down
2 changes: 1 addition & 1 deletion backend/internal/core/services/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func TestMain(m *testing.M) {
tClient = client
tRepos = repo.New(tClient, tbus, os.TempDir()+"/homebox")
tSvc = New(tRepos)
defer client.Close()
defer func() { _ = client.Close() }()

bootstrap()
tCtx = Context{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// / Package eventbus provides an interface for event bus.
// Package eventbus provides an interface for event bus.
package eventbus

import (
Expand Down
1 change: 1 addition & 0 deletions backend/internal/core/services/reporting/import.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package reporting provides a way to import CSV files into the database.
package reporting

import (
Expand Down
8 changes: 4 additions & 4 deletions backend/internal/core/services/reporting/io_sheet.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func (s *IOSheet) Read(data io.Reader) error {
return nil
}

// Write writes the sheet to a writer.
// ReadItems writes the sheet to a writer.
func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid.UUID, repos *repo.AllRepos) error {
s.Rows = make([]ExportTSVRow, len(items))

Expand All @@ -162,9 +162,9 @@ func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid.
item := items[i]

// TODO: Support fetching nested locations
locId := item.Location.ID
locID := item.Location.ID

locPaths, err := repos.Locations.PathForLoc(context.Background(), GID, locId)
locPaths, err := repos.Locations.PathForLoc(context.Background(), GID, locID)
if err != nil {
log.Error().Err(err).Msg("could not get location path")
return err
Expand Down Expand Up @@ -252,7 +252,7 @@ func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid.
return nil
}

// Writes the current sheet to a writer in TSV format.
// TSV writes the current sheet to a writer in TSV format.
func (s *IOSheet) TSV() ([][]string, error) {
memcsv := make([][]string, len(s.Rows)+1)

Expand Down

0 comments on commit e8449b3

Please sign in to comment.