feat: add a new REST endpoint - GET /api/v1/user (#7)
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
Reviewed-on: #7
This commit is contained in:
parent
ffcb965590
commit
79bc3eed46
9
Makefile
9
Makefile
|
@ -9,18 +9,23 @@ install-counterfeiter:
|
|||
@echo "Installing github.com/maxbrunsfeld/counterfeiter..."
|
||||
cd ./internal/tools && go install github.com/maxbrunsfeld/counterfeiter/v6
|
||||
|
||||
.PHONY: install-swag
|
||||
install-swag:
|
||||
@echo "Installing github.com/swaggo/swag..."
|
||||
cd ./internal/tools && go install github.com/swaggo/swag/cmd/swag
|
||||
|
||||
.PHONY: install-golangci-lint
|
||||
install-golangci-lint:
|
||||
@echo "Installing github.com/golangci/golangci-lint..."
|
||||
cd ./internal/tools && go install github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
|
||||
.PHONY: install-tools
|
||||
install-tools: install-golangci-lint install-counterfeiter
|
||||
install-tools: install-golangci-lint install-counterfeiter install-swag
|
||||
|
||||
.PHONY: install
|
||||
install: install-tools install-git-hooks
|
||||
|
||||
.PHONY: generate
|
||||
generate: install-counterfeiter
|
||||
generate: install-counterfeiter install-swag
|
||||
@echo "Running go generate..."
|
||||
go generate ./...
|
|
@ -15,6 +15,9 @@ import (
|
|||
"gitea.dwysokinski.me/twhelp/sessions/cmd/sessions/internal"
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/bundb"
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/router/meta"
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/router/rest"
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/service"
|
||||
"github.com/kelseyhightower/envconfig"
|
||||
"github.com/uptrace/bun"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
|
@ -80,10 +83,38 @@ type serverConfig struct {
|
|||
}
|
||||
|
||||
func newServer(cfg serverConfig) (*http.Server, error) {
|
||||
apiCfg, err := newAPIConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("newAPIConfig: %w", err)
|
||||
}
|
||||
|
||||
// repos
|
||||
userRepo := bundb.NewUser(cfg.db)
|
||||
apiKeyRepo := bundb.NewAPIKey(cfg.db)
|
||||
|
||||
// services
|
||||
userSvc := service.NewUser(userRepo)
|
||||
apiKeySvc := service.NewAPIKey(apiKeyRepo, userSvc)
|
||||
|
||||
// router
|
||||
r := chi.NewRouter()
|
||||
r.Use(getChiMiddlewares(cfg.logger)...)
|
||||
r.Mount(metaEndpointsPrefix, meta.NewRouter([]meta.Checker{bundb.NewChecker(cfg.db)}))
|
||||
r.Mount("/api", rest.NewRouter(rest.RouterConfig{
|
||||
APIKeyVerifier: apiKeySvc,
|
||||
CORS: rest.CORSConfig{
|
||||
Enabled: apiCfg.CORSEnabled,
|
||||
AllowedOrigins: apiCfg.CORSAllowedOrigins,
|
||||
AllowedMethods: apiCfg.CORSAllowedMethods,
|
||||
AllowCredentials: apiCfg.CORSAllowCredentials,
|
||||
MaxAge: int(apiCfg.CORSMaxAge),
|
||||
},
|
||||
Swagger: rest.SwaggerConfig{
|
||||
Enabled: apiCfg.SwaggerEnabled,
|
||||
Host: apiCfg.SwaggerHost,
|
||||
Schemes: apiCfg.SwaggerSchemes,
|
||||
},
|
||||
}))
|
||||
|
||||
return &http.Server{
|
||||
Addr: ":" + defaultPort,
|
||||
|
@ -95,6 +126,25 @@ func newServer(cfg serverConfig) (*http.Server, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
type apiConfig struct {
|
||||
SwaggerEnabled bool `envconfig:"SWAGGER_ENABLED" default:"true"`
|
||||
SwaggerHost string `envconfig:"SWAGGER_HOST" default:""`
|
||||
SwaggerSchemes []string `envconfig:"SWAGGER_SCHEMES" default:"http,https"`
|
||||
CORSEnabled bool `envconfig:"CORS_ENABLED" default:"false"`
|
||||
CORSAllowedOrigins []string `envconfig:"CORS_ALLOWED_ORIGINS" default:""`
|
||||
CORSAllowCredentials bool `envconfig:"CORS_ALLOW_CREDENTIALS" default:"false"`
|
||||
CORSAllowedMethods []string `envconfig:"CORS_ALLOWED_METHODS" default:"HEAD,GET"`
|
||||
CORSMaxAge uint32 `envconfig:"CORS_MAX_AGE" default:"300"`
|
||||
}
|
||||
|
||||
func newAPIConfig() (apiConfig, error) {
|
||||
var cfg apiConfig
|
||||
if err := envconfig.Process("API", &cfg); err != nil {
|
||||
return apiConfig{}, fmt.Errorf("envconfig.Process: %w", err)
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func getChiMiddlewares(logger *zap.Logger) chi.Middlewares {
|
||||
return chi.Middlewares{
|
||||
middleware.RealIP,
|
||||
|
|
16
go.mod
16
go.mod
|
@ -6,12 +6,15 @@ require (
|
|||
gitea.dwysokinski.me/Kichiyaki/chizap v0.2.1
|
||||
github.com/cenkalti/backoff/v4 v4.2.0
|
||||
github.com/go-chi/chi/v5 v5.0.7
|
||||
github.com/go-chi/cors v1.2.1
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa
|
||||
github.com/kelseyhightower/envconfig v1.4.0
|
||||
github.com/ory/dockertest/v3 v3.9.1
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/swaggo/http-swagger v1.3.3
|
||||
github.com/swaggo/swag v1.8.7
|
||||
github.com/uptrace/bun v1.1.8
|
||||
github.com/uptrace/bun/dbfixture v1.1.8
|
||||
github.com/uptrace/bun/dialect/pgdialect v1.1.8
|
||||
|
@ -22,6 +25,7 @@ require (
|
|||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||
github.com/containerd/continuity v0.3.0 // indirect
|
||||
|
@ -31,10 +35,16 @@ require (
|
|||
github.com/docker/docker v20.10.7+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/spec v0.20.6 // indirect
|
||||
github.com/go-openapi/swag v0.19.15 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.1 // indirect
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
|
@ -44,6 +54,7 @@ require (
|
|||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe // indirect
|
||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
|
@ -54,9 +65,10 @@ require (
|
|||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.7.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d // indirect
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 // indirect
|
||||
gopkg.in/yaml.v2 v2.3.0 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
mellium.im/sasl v0.3.0 // indirect
|
||||
)
|
||||
|
|
50
go.sum
50
go.sum
|
@ -3,6 +3,8 @@ gitea.dwysokinski.me/Kichiyaki/chizap v0.2.1/go.mod h1:q+HrVxr1rf95wyuSTBt4Sa54U
|
|||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||
|
@ -19,6 +21,7 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
|
|||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
|
@ -36,6 +39,18 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
|
|||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=
|
||||
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
||||
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
|
||||
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
|
||||
github.com/go-openapi/spec v0.20.6 h1:ich1RQ3WDbfoeTqTAb+5EIxNmpKVJZWBNah9RAT0jIQ=
|
||||
github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
|
@ -58,20 +73,31 @@ github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa h1:s+4MhCQ6YrzisK6
|
|||
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
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/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
|
||||
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2 h1:hRGSmZu7j271trc9sneMrpOW7GN5ngLm8YUZIPzf394=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||
|
@ -107,6 +133,12 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe h1:K8pHPVoTgxFJt1lXuIzzOX7zZhZFldJQK/CgKx9BFIc=
|
||||
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
|
||||
github.com/swaggo/http-swagger v1.3.3 h1:Hu5Z0L9ssyBLofaama21iYaF2VbWyA8jdohaaCGpHsc=
|
||||
github.com/swaggo/http-swagger v1.3.3/go.mod h1:sE+4PjD89IxMPm77FnkDz0sdO+p5lbXzrVWT6OTVVGo=
|
||||
github.com/swaggo/swag v1.8.7 h1:2K9ivTD3teEO+2fXV6zrZKDqk5IuU2aJtBDo8U7omWU=
|
||||
github.com/swaggo/swag v1.8.7/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo=
|
||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
|
||||
|
@ -152,14 +184,16 @@ golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9Tl
|
|||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -172,6 +206,7 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -180,23 +215,30 @@ golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
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.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
@ -2,6 +2,7 @@ package bundb
|
|||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
|
@ -36,6 +37,26 @@ func (a *APIKey) Create(ctx context.Context, params domain.CreateAPIKeyParams) (
|
|||
return apiKey.ToDomain(), nil
|
||||
}
|
||||
|
||||
func (a *APIKey) Get(ctx context.Context, key string) (domain.APIKey, error) {
|
||||
var ak model.APIKey
|
||||
|
||||
if err := a.db.NewSelect().
|
||||
Model(&ak).
|
||||
Where("key = ?", key).
|
||||
Scan(ctx); err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return domain.APIKey{}, domain.APIKeyNotFoundError{Key: key}
|
||||
}
|
||||
return domain.APIKey{}, fmt.Errorf(
|
||||
"something went wrong while selecting api key (key=%s) from the db: %w",
|
||||
key,
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
return ak.ToDomain(), nil
|
||||
}
|
||||
|
||||
func mapCreateAPIKeyError(err error, params domain.CreateAPIKeyParams) error {
|
||||
var pgError pgdriver.Error
|
||||
if !errors.As(err, &pgError) {
|
||||
|
|
|
@ -33,7 +33,6 @@ func TestAPIKey_Create(t *testing.T) {
|
|||
assert.Equal(t, params.Key(), apiKey.Key)
|
||||
assert.Equal(t, params.UserID(), apiKey.UserID)
|
||||
assert.WithinDuration(t, time.Now(), apiKey.CreatedAt, time.Second)
|
||||
assert.Zero(t, apiKey.LastUsedAt)
|
||||
})
|
||||
|
||||
t.Run("ERR: player doesn't exist", func(t *testing.T) {
|
||||
|
@ -66,3 +65,30 @@ func TestAPIKey_Create(t *testing.T) {
|
|||
assert.Zero(t, apiKey)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAPIKey_Get(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
db := newDB(t)
|
||||
fixture := loadFixtures(t, db)
|
||||
repo := bundb.NewAPIKey(db)
|
||||
apiKeyFromFixture := fixture.apiKey(t, "user-1-api-key-1")
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ak, err := repo.Get(context.Background(), apiKeyFromFixture.Key)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, apiKeyFromFixture, ak)
|
||||
})
|
||||
|
||||
t.Run("ERR: API key not found", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ak, err := repo.Get(context.Background(), apiKeyFromFixture.Key+"1")
|
||||
assert.ErrorIs(t, err, domain.APIKeyNotFoundError{
|
||||
Key: apiKeyFromFixture.Key + "1",
|
||||
})
|
||||
assert.Zero(t, ak)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -10,11 +10,10 @@ import (
|
|||
type APIKey struct {
|
||||
bun.BaseModel `bun:"base_model,table:api_keys,alias:ak"`
|
||||
|
||||
ID int64 `bun:"id,pk,autoincrement,identity"`
|
||||
Key string `bun:"key,nullzero,type:varchar(255),notnull,unique"`
|
||||
UserID int64 `bun:"user_id,nullzero,notnull"`
|
||||
CreatedAt time.Time `bun:"created_at,nullzero,notnull,default:current_timestamp"`
|
||||
LastUsedAt time.Time `bun:"last_used_at,nullzero"`
|
||||
ID int64 `bun:"id,pk,autoincrement,identity"`
|
||||
Key string `bun:"key,nullzero,type:varchar(255),notnull,unique"`
|
||||
UserID int64 `bun:"user_id,nullzero,notnull"`
|
||||
CreatedAt time.Time `bun:"created_at,nullzero,notnull,default:current_timestamp"`
|
||||
}
|
||||
|
||||
func NewAPIKey(p domain.CreateAPIKeyParams) APIKey {
|
||||
|
@ -27,10 +26,9 @@ func NewAPIKey(p domain.CreateAPIKeyParams) APIKey {
|
|||
|
||||
func (a *APIKey) ToDomain() domain.APIKey {
|
||||
return domain.APIKey{
|
||||
ID: a.ID,
|
||||
Key: a.Key,
|
||||
UserID: a.UserID,
|
||||
CreatedAt: a.CreatedAt,
|
||||
LastUsedAt: a.LastUsedAt,
|
||||
ID: a.ID,
|
||||
Key: a.Key,
|
||||
UserID: a.UserID,
|
||||
CreatedAt: a.CreatedAt,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,18 +14,15 @@ func TestAPIKey(t *testing.T) {
|
|||
t.Parallel()
|
||||
|
||||
var id int64 = 123
|
||||
lastUsedAt := time.Now().Add(-5 * time.Minute)
|
||||
params, err := domain.NewCreateAPIKeyParams(uuid.NewString(), 1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
result := model.NewAPIKey(params)
|
||||
result.ID = id
|
||||
result.LastUsedAt = lastUsedAt
|
||||
|
||||
apiKey := result.ToDomain()
|
||||
assert.Equal(t, id, apiKey.ID)
|
||||
assert.Equal(t, params.Key(), apiKey.Key)
|
||||
assert.Equal(t, params.UserID(), apiKey.UserID)
|
||||
assert.WithinDuration(t, time.Now(), apiKey.CreatedAt, 10*time.Millisecond)
|
||||
assert.Equal(t, lastUsedAt, apiKey.LastUsedAt)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package domain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -9,11 +10,10 @@ const (
|
|||
)
|
||||
|
||||
type APIKey struct {
|
||||
ID int64
|
||||
Key string
|
||||
UserID int64
|
||||
CreatedAt time.Time
|
||||
LastUsedAt time.Time
|
||||
ID int64
|
||||
Key string
|
||||
UserID int64
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type CreateAPIKeyParams struct {
|
||||
|
@ -48,3 +48,19 @@ func (c CreateAPIKeyParams) Key() string {
|
|||
func (c CreateAPIKeyParams) UserID() int64 {
|
||||
return c.userID
|
||||
}
|
||||
|
||||
type APIKeyNotFoundError struct {
|
||||
Key string
|
||||
}
|
||||
|
||||
func (e APIKeyNotFoundError) Error() string {
|
||||
return fmt.Sprintf("API key (key=%s) not found", e.Key)
|
||||
}
|
||||
|
||||
func (e APIKeyNotFoundError) UserError() string {
|
||||
return e.Error()
|
||||
}
|
||||
|
||||
func (e APIKeyNotFoundError) Code() ErrorCode {
|
||||
return ErrorCodeEntityNotFound
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package domain_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/domain"
|
||||
|
@ -62,3 +63,15 @@ func TestNewCreateAPIKeyParams(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAPIKeyNotFoundError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
err := domain.APIKeyNotFoundError{
|
||||
Key: uuid.NewString(),
|
||||
}
|
||||
var _ domain.Error = err
|
||||
assert.Equal(t, fmt.Sprintf("API key (key=%s) not found", err.Key), err.Error())
|
||||
assert.Equal(t, err.Error(), err.UserError())
|
||||
assert.Equal(t, domain.ErrorCodeEntityNotFound, err.Code())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
*.go
|
||||
swagger.json
|
||||
swagger.yaml
|
|
@ -0,0 +1,120 @@
|
|||
// Code generated by counterfeiter. DO NOT EDIT.
|
||||
package mock
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/domain"
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/router/rest"
|
||||
)
|
||||
|
||||
type FakeAPIKeyVerifier struct {
|
||||
VerifyStub func(context.Context, string) (domain.User, error)
|
||||
verifyMutex sync.RWMutex
|
||||
verifyArgsForCall []struct {
|
||||
arg1 context.Context
|
||||
arg2 string
|
||||
}
|
||||
verifyReturns struct {
|
||||
result1 domain.User
|
||||
result2 error
|
||||
}
|
||||
verifyReturnsOnCall map[int]struct {
|
||||
result1 domain.User
|
||||
result2 error
|
||||
}
|
||||
invocations map[string][][]interface{}
|
||||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (fake *FakeAPIKeyVerifier) Verify(arg1 context.Context, arg2 string) (domain.User, error) {
|
||||
fake.verifyMutex.Lock()
|
||||
ret, specificReturn := fake.verifyReturnsOnCall[len(fake.verifyArgsForCall)]
|
||||
fake.verifyArgsForCall = append(fake.verifyArgsForCall, struct {
|
||||
arg1 context.Context
|
||||
arg2 string
|
||||
}{arg1, arg2})
|
||||
stub := fake.VerifyStub
|
||||
fakeReturns := fake.verifyReturns
|
||||
fake.recordInvocation("Verify", []interface{}{arg1, arg2})
|
||||
fake.verifyMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1, arg2)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakeAPIKeyVerifier) VerifyCallCount() int {
|
||||
fake.verifyMutex.RLock()
|
||||
defer fake.verifyMutex.RUnlock()
|
||||
return len(fake.verifyArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeAPIKeyVerifier) VerifyCalls(stub func(context.Context, string) (domain.User, error)) {
|
||||
fake.verifyMutex.Lock()
|
||||
defer fake.verifyMutex.Unlock()
|
||||
fake.VerifyStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeAPIKeyVerifier) VerifyArgsForCall(i int) (context.Context, string) {
|
||||
fake.verifyMutex.RLock()
|
||||
defer fake.verifyMutex.RUnlock()
|
||||
argsForCall := fake.verifyArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2
|
||||
}
|
||||
|
||||
func (fake *FakeAPIKeyVerifier) VerifyReturns(result1 domain.User, result2 error) {
|
||||
fake.verifyMutex.Lock()
|
||||
defer fake.verifyMutex.Unlock()
|
||||
fake.VerifyStub = nil
|
||||
fake.verifyReturns = struct {
|
||||
result1 domain.User
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeAPIKeyVerifier) VerifyReturnsOnCall(i int, result1 domain.User, result2 error) {
|
||||
fake.verifyMutex.Lock()
|
||||
defer fake.verifyMutex.Unlock()
|
||||
fake.VerifyStub = nil
|
||||
if fake.verifyReturnsOnCall == nil {
|
||||
fake.verifyReturnsOnCall = make(map[int]struct {
|
||||
result1 domain.User
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.verifyReturnsOnCall[i] = struct {
|
||||
result1 domain.User
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeAPIKeyVerifier) Invocations() map[string][][]interface{} {
|
||||
fake.invocationsMutex.RLock()
|
||||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.verifyMutex.RLock()
|
||||
defer fake.verifyMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
for key, value := range fake.invocations {
|
||||
copiedInvocations[key] = value
|
||||
}
|
||||
return copiedInvocations
|
||||
}
|
||||
|
||||
func (fake *FakeAPIKeyVerifier) recordInvocation(key string, args []interface{}) {
|
||||
fake.invocationsMutex.Lock()
|
||||
defer fake.invocationsMutex.Unlock()
|
||||
if fake.invocations == nil {
|
||||
fake.invocations = map[string][][]interface{}{}
|
||||
}
|
||||
if fake.invocations[key] == nil {
|
||||
fake.invocations[key] = [][]interface{}{}
|
||||
}
|
||||
fake.invocations[key] = append(fake.invocations[key], args)
|
||||
}
|
||||
|
||||
var _ rest.APIKeyVerifier = new(FakeAPIKeyVerifier)
|
|
@ -0,0 +1,11 @@
|
|||
package model
|
||||
|
||||
type APIError struct {
|
||||
//nolint:lll
|
||||
Code string `json:"code" enums:"entity-not-found,route-not-found,method-not-allowed,validation-error,unauthorized,already-exists,internal-server-error"`
|
||||
Message string `json:"message"`
|
||||
} // @name ApiError
|
||||
|
||||
type ErrorResp struct {
|
||||
Error APIError `json:"error"`
|
||||
} // @name ErrorResp
|
|
@ -0,0 +1,29 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/domain"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CreatedAt time.Time `json:"createdAt" format:"date-time"`
|
||||
} // @name User
|
||||
|
||||
func NewUser(u domain.User) User {
|
||||
return User{
|
||||
ID: u.ID,
|
||||
Name: u.Name,
|
||||
CreatedAt: u.CreatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
type GetUserResp struct {
|
||||
Data User `json:"data"`
|
||||
} // @name GetUserResp
|
||||
|
||||
func NewGetUserResp(u domain.User) GetUserResp {
|
||||
return GetUserResp{Data: NewUser(u)}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/domain"
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/router/rest/internal/model"
|
||||
)
|
||||
|
||||
type authCtxKey struct{}
|
||||
|
||||
func authMiddleware(verifier APIKeyVerifier) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
key := r.Header.Get("X-API-Key")
|
||||
if key == "" {
|
||||
renderJSON(w, http.StatusUnauthorized, model.ErrorResp{
|
||||
Error: model.APIError{
|
||||
Code: "unauthorized",
|
||||
Message: "invalid API key",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
u, err := verifier.Verify(r.Context(), key)
|
||||
if err != nil {
|
||||
renderJSON(w, http.StatusUnauthorized, model.ErrorResp{
|
||||
Error: model.APIError{
|
||||
Code: "unauthorized",
|
||||
Message: "invalid API key",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r.WithContext(userToContext(r.Context(), u)))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func userToContext(ctx context.Context, u domain.User) context.Context {
|
||||
return context.WithValue(ctx, authCtxKey{}, u)
|
||||
}
|
||||
|
||||
func userFromContext(ctx context.Context) (domain.User, bool) {
|
||||
u, ok := ctx.Value(authCtxKey{}).(domain.User)
|
||||
return u, ok
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package rest
|
||||
|
||||
//go:generate swag init -g openapi.go -o "./internal/docs"
|
||||
|
||||
// @title Sessions API
|
||||
// @version 1.0
|
||||
|
||||
// @contact.name Dawid Wysokiński
|
||||
// @contact.url https://dwysokinski.me
|
||||
// @contact.email contact@dwysokinski.me
|
||||
|
||||
// @BasePath /api/v1
|
||||
|
||||
// @query.collection.format multi
|
||||
|
||||
// @securityDefinitions.apikey ApiKeyAuth
|
||||
// @in header
|
||||
// @name X-Api-Key
|
|
@ -0,0 +1,151 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/domain"
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/router/rest/internal/docs"
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/router/rest/internal/model"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/cors"
|
||||
httpSwagger "github.com/swaggo/http-swagger"
|
||||
)
|
||||
|
||||
//go:generate counterfeiter -generate
|
||||
|
||||
type CORSConfig struct {
|
||||
Enabled bool
|
||||
AllowedOrigins []string
|
||||
AllowedMethods []string
|
||||
AllowCredentials bool
|
||||
MaxAge int
|
||||
}
|
||||
|
||||
type SwaggerConfig struct {
|
||||
Enabled bool
|
||||
Host string
|
||||
Schemes []string
|
||||
}
|
||||
|
||||
//counterfeiter:generate -o internal/mock/api_key_verifier.gen.go . APIKeyVerifier
|
||||
type APIKeyVerifier interface {
|
||||
Verify(ctx context.Context, key string) (domain.User, error)
|
||||
}
|
||||
|
||||
type RouterConfig struct {
|
||||
APIKeyVerifier APIKeyVerifier
|
||||
CORS CORSConfig
|
||||
Swagger SwaggerConfig
|
||||
}
|
||||
|
||||
func NewRouter(cfg RouterConfig) *chi.Mux {
|
||||
// handlers
|
||||
uh := userHandler{}
|
||||
|
||||
router := chi.NewRouter()
|
||||
|
||||
if cfg.CORS.Enabled {
|
||||
router.Use(cors.Handler(cors.Options{
|
||||
AllowedOrigins: cfg.CORS.AllowedOrigins,
|
||||
AllowCredentials: cfg.CORS.AllowCredentials,
|
||||
AllowedMethods: cfg.CORS.AllowedMethods,
|
||||
AllowedHeaders: []string{"Origin", "Content-Length", "Content-Type", "X-API-Key"},
|
||||
MaxAge: cfg.CORS.MaxAge,
|
||||
}))
|
||||
}
|
||||
|
||||
router.NotFound(routeNotFoundHandler)
|
||||
router.MethodNotAllowed(methodNotAllowedHandler)
|
||||
|
||||
router.Route("/v1", func(r chi.Router) {
|
||||
if cfg.Swagger.Enabled {
|
||||
if cfg.Swagger.Host != "" {
|
||||
docs.SwaggerInfo.Host = cfg.Swagger.Host
|
||||
}
|
||||
if len(cfg.Swagger.Schemes) > 0 {
|
||||
docs.SwaggerInfo.Schemes = cfg.Swagger.Schemes
|
||||
}
|
||||
r.Get("/swagger/*", httpSwagger.Handler())
|
||||
}
|
||||
|
||||
authMw := authMiddleware(cfg.APIKeyVerifier)
|
||||
|
||||
r.With(authMw).Get("/user", uh.getAuthenticated)
|
||||
})
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
func routeNotFoundHandler(w http.ResponseWriter, _ *http.Request) {
|
||||
renderJSON(w, http.StatusNotFound, model.ErrorResp{
|
||||
Error: model.APIError{
|
||||
Code: "route-not-found",
|
||||
Message: "route not found",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func methodNotAllowedHandler(w http.ResponseWriter, _ *http.Request) {
|
||||
renderJSON(w, http.StatusMethodNotAllowed, model.ErrorResp{
|
||||
Error: model.APIError{
|
||||
Code: "method-not-allowed",
|
||||
Message: "method not allowed",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// type internalServerError struct {
|
||||
// err error
|
||||
// }
|
||||
//
|
||||
// func (e internalServerError) Error() string {
|
||||
// return e.err.Error()
|
||||
// }
|
||||
//
|
||||
// func (e internalServerError) UserError() string {
|
||||
// return "internal server error"
|
||||
// }
|
||||
//
|
||||
// func (e internalServerError) Code() domain.ErrorCode {
|
||||
// return domain.ErrorCodeUnknown
|
||||
// }
|
||||
//
|
||||
// func (e internalServerError) Unwrap() error {
|
||||
// return e.err
|
||||
// }
|
||||
//
|
||||
// func renderErr(w http.ResponseWriter, err error) {
|
||||
// var userError domain.Error
|
||||
// if !errors.As(err, &userError) {
|
||||
// userError = internalServerError{err: err}
|
||||
// }
|
||||
// renderJSON(w, errorCodeToHTTPStatus(userError.Code()), model.ErrorResp{
|
||||
// Error: model.APIError{
|
||||
// Code: userError.Code().String(),
|
||||
// Message: userError.UserError(),
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// func errorCodeToHTTPStatus(code domain.ErrorCode) int {
|
||||
// switch code {
|
||||
// case domain.ErrorCodeValidationError:
|
||||
// return http.StatusBadRequest
|
||||
// case domain.ErrorCodeEntityNotFound:
|
||||
// return http.StatusNotFound
|
||||
// case domain.ErrorCodeAlreadyExists:
|
||||
// return http.StatusConflict
|
||||
// case domain.ErrorCodeUnknown:
|
||||
// fallthrough
|
||||
// default:
|
||||
// return http.StatusInternalServerError
|
||||
// }
|
||||
// }
|
||||
|
||||
func renderJSON(w http.ResponseWriter, status int, data any) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
_ = json.NewEncoder(w).Encode(data)
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
package rest_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/router/rest"
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/router/rest/internal/model"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRouteNotFound(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
expectedResp := &model.ErrorResp{
|
||||
Error: model.APIError{
|
||||
Code: "route-not-found",
|
||||
Message: "route not found",
|
||||
},
|
||||
}
|
||||
|
||||
resp := doRequest(rest.NewRouter(rest.RouterConfig{}), http.MethodGet, "/v1/"+uuid.NewString(), "", nil)
|
||||
defer resp.Body.Close()
|
||||
assertJSONResponse(t, resp, http.StatusNotFound, expectedResp, &model.ErrorResp{})
|
||||
}
|
||||
|
||||
func TestMethodNotAllowed(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
expectedResp := &model.ErrorResp{
|
||||
Error: model.APIError{
|
||||
Code: "method-not-allowed",
|
||||
Message: "method not allowed",
|
||||
},
|
||||
}
|
||||
|
||||
resp := doRequest(rest.NewRouter(rest.RouterConfig{
|
||||
Swagger: rest.SwaggerConfig{
|
||||
Enabled: true,
|
||||
},
|
||||
}), http.MethodPost, "/v1/swagger/index.html", "", nil)
|
||||
defer resp.Body.Close()
|
||||
assertJSONResponse(t, resp, http.StatusMethodNotAllowed, expectedResp, &model.ErrorResp{})
|
||||
}
|
||||
|
||||
func TestSwagger(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
target string
|
||||
expectedContentType string
|
||||
}{
|
||||
{
|
||||
name: "/v1/swagger/index.html",
|
||||
target: "/v1/swagger/index.html",
|
||||
expectedContentType: "text/html; charset=utf-8",
|
||||
},
|
||||
{
|
||||
name: "/v1/swagger/doc.json",
|
||||
target: "/v1/swagger/doc.json",
|
||||
expectedContentType: "application/json; charset=utf-8",
|
||||
},
|
||||
}
|
||||
router := rest.NewRouter(rest.RouterConfig{
|
||||
Swagger: rest.SwaggerConfig{
|
||||
Enabled: true,
|
||||
},
|
||||
})
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
resp := doRequest(router, http.MethodGet, tt.target, "", nil)
|
||||
defer resp.Body.Close()
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
assert.Equal(t, tt.expectedContentType, resp.Header.Get("Content-Type"))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func doRequest(mux chi.Router, method, target, apiKey string, body io.Reader) *http.Response {
|
||||
rr := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(method, target, body)
|
||||
if apiKey != "" {
|
||||
req.Header.Set("X-Api-Key", apiKey)
|
||||
}
|
||||
mux.ServeHTTP(rr, req)
|
||||
return rr.Result()
|
||||
}
|
||||
|
||||
func assertJSONResponse(tb testing.TB, resp *http.Response, expectedStatus int, expected any, target any) {
|
||||
tb.Helper()
|
||||
|
||||
assert.Equal(tb, "application/json", resp.Header.Get("Content-Type"))
|
||||
assert.Equal(tb, expectedStatus, resp.StatusCode)
|
||||
assert.NoError(tb, json.NewDecoder(resp.Body).Decode(target))
|
||||
opts := cmp.Options{
|
||||
cmpopts.IgnoreUnexported(time.Time{}),
|
||||
}
|
||||
assert.Empty(tb, cmp.Diff(expected, target, opts...))
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/router/rest/internal/model"
|
||||
)
|
||||
|
||||
type userHandler struct {
|
||||
}
|
||||
|
||||
// @ID getAuthenticatedUser
|
||||
// @Summary Get the authenticated user
|
||||
// @Description Get the authenticated user
|
||||
// @Tags users
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.GetUserResp
|
||||
// @Success 401 {object} model.ErrorResp
|
||||
// @Failure 500 {object} model.ErrorResp
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /user [get]
|
||||
func (h *userHandler) getAuthenticated(w http.ResponseWriter, r *http.Request) {
|
||||
u, _ := userFromContext(r.Context())
|
||||
renderJSON(w, http.StatusOK, model.NewGetUserResp(u))
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
package rest_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/domain"
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/router/rest"
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/router/rest/internal/mock"
|
||||
"gitea.dwysokinski.me/twhelp/sessions/internal/router/rest/internal/model"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func TestUser_getAuthenticated(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
now := time.Now()
|
||||
apiKey := uuid.NewString()
|
||||
tests := []struct {
|
||||
name string
|
||||
setup func(apiKeySvc *mock.FakeAPIKeyVerifier)
|
||||
apiKey string
|
||||
expectedStatus int
|
||||
target any
|
||||
expectedResponse any
|
||||
}{
|
||||
{
|
||||
name: "OK",
|
||||
setup: func(apiKeySvc *mock.FakeAPIKeyVerifier) {
|
||||
apiKeySvc.VerifyCalls(func(ctx context.Context, key string) (domain.User, error) {
|
||||
if key != apiKey {
|
||||
return domain.User{}, domain.APIKeyNotFoundError{
|
||||
Key: key,
|
||||
}
|
||||
}
|
||||
|
||||
return domain.User{
|
||||
ID: 111,
|
||||
Name: "name",
|
||||
CreatedAt: now,
|
||||
}, nil
|
||||
})
|
||||
},
|
||||
apiKey: apiKey,
|
||||
expectedStatus: http.StatusOK,
|
||||
target: &model.GetUserResp{},
|
||||
expectedResponse: &model.GetUserResp{
|
||||
Data: model.User{
|
||||
ID: 111,
|
||||
Name: "name",
|
||||
CreatedAt: now,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ERR: apiKey == \"\"",
|
||||
setup: func(apiKeySvc *mock.FakeAPIKeyVerifier) {},
|
||||
apiKey: "",
|
||||
expectedStatus: http.StatusUnauthorized,
|
||||
target: &model.ErrorResp{},
|
||||
expectedResponse: &model.ErrorResp{
|
||||
Error: model.APIError{
|
||||
Code: "unauthorized",
|
||||
Message: "invalid API key",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ERR: unexpected API key",
|
||||
setup: func(apiKeySvc *mock.FakeAPIKeyVerifier) {
|
||||
apiKeySvc.VerifyCalls(func(ctx context.Context, key string) (domain.User, error) {
|
||||
if key != apiKey {
|
||||
return domain.User{}, domain.APIKeyNotFoundError{
|
||||
Key: key,
|
||||
}
|
||||
}
|
||||
|
||||
return domain.User{
|
||||
ID: 111,
|
||||
Name: "name",
|
||||
CreatedAt: now,
|
||||
}, nil
|
||||
})
|
||||
},
|
||||
apiKey: uuid.NewString(),
|
||||
expectedStatus: http.StatusUnauthorized,
|
||||
target: &model.ErrorResp{},
|
||||
expectedResponse: &model.ErrorResp{
|
||||
Error: model.APIError{
|
||||
Code: "unauthorized",
|
||||
Message: "invalid API key",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
apiKeySvc := &mock.FakeAPIKeyVerifier{}
|
||||
tt.setup(apiKeySvc)
|
||||
|
||||
router := rest.NewRouter(rest.RouterConfig{
|
||||
APIKeyVerifier: apiKeySvc,
|
||||
})
|
||||
|
||||
resp := doRequest(router, http.MethodGet, "/v1/user", tt.apiKey, nil)
|
||||
defer resp.Body.Close()
|
||||
assertJSONResponse(t, resp, tt.expectedStatus, tt.expectedResponse, tt.target)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
|
@ -12,6 +12,7 @@ import (
|
|||
//counterfeiter:generate -o internal/mock/api_key_repository.gen.go . APIKeyRepository
|
||||
type APIKeyRepository interface {
|
||||
Create(ctx context.Context, params domain.CreateAPIKeyParams) (domain.APIKey, error)
|
||||
Get(ctx context.Context, key string) (domain.APIKey, error)
|
||||
}
|
||||
|
||||
//counterfeiter:generate -o internal/mock/user_getter.gen.go . UserGetter
|
||||
|
@ -54,3 +55,24 @@ func (a *APIKey) Create(ctx context.Context, userID int64) (domain.APIKey, error
|
|||
|
||||
return apiKey, nil
|
||||
}
|
||||
|
||||
func (a *APIKey) Verify(ctx context.Context, keyStr string) (domain.User, error) {
|
||||
key, err := uuid.Parse(keyStr)
|
||||
if err != nil {
|
||||
return domain.User{}, domain.APIKeyNotFoundError{
|
||||
Key: keyStr,
|
||||
}
|
||||
}
|
||||
|
||||
ak, err := a.repo.Get(ctx, key.String())
|
||||
if err != nil {
|
||||
return domain.User{}, fmt.Errorf("APIKeyRepository.Get: %w", err)
|
||||
}
|
||||
|
||||
user, err := a.userSvc.Get(ctx, ak.UserID)
|
||||
if err != nil {
|
||||
return domain.User{}, fmt.Errorf("UserService.Get: %w", err)
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
|
|
@ -53,3 +53,45 @@ func TestAPIKey_Create(t *testing.T) {
|
|||
assert.Zero(t, ak)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAPIKey_Verify(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
apiKeyRepo := &mock.FakeAPIKeyRepository{}
|
||||
apiKeyRepo.GetCalls(func(ctx context.Context, key string) (domain.APIKey, error) {
|
||||
return domain.APIKey{
|
||||
ID: 1,
|
||||
Key: key,
|
||||
UserID: 125,
|
||||
CreatedAt: time.Now(),
|
||||
}, nil
|
||||
})
|
||||
|
||||
userSvc := &mock.FakeUserGetter{}
|
||||
userSvc.GetCalls(func(ctx context.Context, id int64) (domain.User, error) {
|
||||
return domain.User{
|
||||
ID: id,
|
||||
Name: uuid.NewString(),
|
||||
CreatedAt: time.Now(),
|
||||
}, nil
|
||||
})
|
||||
|
||||
user, err := service.NewAPIKey(apiKeyRepo, userSvc).Verify(context.Background(), uuid.NewString())
|
||||
assert.NoError(t, err)
|
||||
assert.Greater(t, user.ID, int64(0))
|
||||
})
|
||||
|
||||
t.Run("ERR: invalid uuid", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
key := "abcd"
|
||||
user, err := service.NewAPIKey(nil, nil).Verify(context.Background(), key)
|
||||
assert.ErrorIs(t, err, domain.APIKeyNotFoundError{
|
||||
Key: key,
|
||||
})
|
||||
assert.Zero(t, user)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ go 1.19
|
|||
require (
|
||||
github.com/golangci/golangci-lint v1.50.1
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.5.0
|
||||
github.com/swaggo/swag v1.8.7
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -15,8 +16,11 @@ require (
|
|||
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
|
||||
github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/OpenPeeDeeP/depguard v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/alexkohler/prealloc v1.0.0 // indirect
|
||||
github.com/alingse/asasalint v0.0.11 // indirect
|
||||
github.com/ashanbrown/forbidigo v1.3.0 // indirect
|
||||
|
@ -31,6 +35,7 @@ require (
|
|||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/charithe/durationcheck v0.0.9 // indirect
|
||||
github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/curioswitch/go-reassign v0.2.0 // indirect
|
||||
github.com/daixiang0/gci v0.8.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
|
@ -42,7 +47,12 @@ require (
|
|||
github.com/firefart/nonamedreturns v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||
github.com/fzipp/gocyclo v0.6.0 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-critic/go-critic v0.6.5 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||
github.com/go-openapi/spec v0.20.4 // indirect
|
||||
github.com/go-openapi/swag v0.19.15 // indirect
|
||||
github.com/go-toolsmith/astcast v1.0.0 // indirect
|
||||
github.com/go-toolsmith/astcopy v1.0.2 // indirect
|
||||
github.com/go-toolsmith/astequal v1.0.3 // indirect
|
||||
|
@ -78,6 +88,7 @@ require (
|
|||
github.com/jgautheron/goconst v1.5.1 // indirect
|
||||
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
|
||||
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/julz/importas v0.1.0 // indirect
|
||||
github.com/kisielk/errcheck v1.6.2 // indirect
|
||||
github.com/kisielk/gotool v1.0.0 // indirect
|
||||
|
@ -90,6 +101,7 @@ require (
|
|||
github.com/leonklingele/grouper v1.1.0 // indirect
|
||||
github.com/lufeee/execinquery v1.2.1 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/maratori/testableexamples v1.0.0 // indirect
|
||||
github.com/maratori/testpackage v1.1.0 // indirect
|
||||
github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect
|
||||
|
@ -121,6 +133,7 @@ require (
|
|||
github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f // indirect
|
||||
github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect
|
||||
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/ryancurrah/gomodguard v1.2.4 // indirect
|
||||
github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect
|
||||
github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect
|
||||
|
@ -153,6 +166,7 @@ require (
|
|||
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
|
||||
github.com/ultraware/funlen v0.0.3 // indirect
|
||||
github.com/ultraware/whitespace v0.0.5 // indirect
|
||||
github.com/urfave/cli/v2 v2.3.0 // indirect
|
||||
github.com/uudashr/gocognit v1.0.6 // indirect
|
||||
github.com/yagipy/maintidx v1.0.0 // indirect
|
||||
github.com/yeya24/promlinter v0.2.0 // indirect
|
||||
|
@ -163,9 +177,10 @@ require (
|
|||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect
|
||||
golang.org/x/mod v0.6.0 // indirect
|
||||
golang.org/x/net v0.1.0 // indirect
|
||||
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect
|
||||
golang.org/x/sys v0.1.0 // indirect
|
||||
golang.org/x/text v0.3.8 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
golang.org/x/tools v0.2.0 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
|
|
|
@ -52,10 +52,16 @@ github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rW
|
|||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
|
||||
github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 h1:+r1rSv4gvYn0wmRjC8X7IAzX8QezqtFV9m0MUHFJgts=
|
||||
github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/OpenPeeDeeP/depguard v1.1.1 h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZdunyA=
|
||||
github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
|
@ -100,6 +106,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
|||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cristalhq/acmd v0.8.1/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ=
|
||||
|
@ -133,6 +141,8 @@ github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwV
|
|||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
|
||||
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-critic/go-critic v0.6.5 h1:fDaR/5GWURljXwF8Eh31T2GZNz9X4jeboS912mWF8Uo=
|
||||
github.com/go-critic/go-critic v0.6.5/go.mod h1:ezfP/Lh7MA6dBNn4c6ab5ALv3sKnZVLx37tr00uuaOY=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
|
@ -144,6 +154,16 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
|
|||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
|
||||
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
|
||||
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
|
||||
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g=
|
||||
|
@ -294,6 +314,8 @@ github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+D
|
|||
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48=
|
||||
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
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/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
|
@ -338,6 +360,10 @@ github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCE
|
|||
github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM=
|
||||
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
|
||||
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI=
|
||||
github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE=
|
||||
github.com/maratori/testpackage v1.1.0 h1:GJY4wlzQhuBusMF1oahQCBtUV/AQ/k69IZ68vxaac2Q=
|
||||
|
@ -448,6 +474,8 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l
|
|||
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1rEOtBp4=
|
||||
github.com/ryancurrah/gomodguard v1.2.4/go.mod h1:+Kem4VjWwvFpUJRJSwa16s1tBJe+vbv02+naTow2f6M=
|
||||
|
@ -466,6 +494,7 @@ github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqP
|
|||
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
|
||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
|
@ -506,12 +535,15 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
|||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
|
||||
github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/swaggo/swag v1.8.7 h1:2K9ivTD3teEO+2fXV6zrZKDqk5IuU2aJtBDo8U7omWU=
|
||||
github.com/swaggo/swag v1.8.7/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
|
||||
github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A=
|
||||
github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM=
|
||||
github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA=
|
||||
|
@ -532,6 +564,8 @@ github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iL
|
|||
github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
|
||||
github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI=
|
||||
github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y=
|
||||
github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY=
|
||||
github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM=
|
||||
|
@ -646,10 +680,12 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -715,6 +751,7 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -742,8 +779,8 @@ 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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/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-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@ -935,6 +972,7 @@ gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
|||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -942,6 +980,7 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
@ -6,4 +6,5 @@ package tools
|
|||
import (
|
||||
_ "github.com/golangci/golangci-lint/cmd/golangci-lint"
|
||||
_ "github.com/maxbrunsfeld/counterfeiter/v6"
|
||||
_ "github.com/swaggo/swag/cmd/swag"
|
||||
)
|
||||
|
|
|
@ -30,6 +30,8 @@ spec:
|
|||
value: "10"
|
||||
- name: DB_MAX_IDLE_CONNECTIONS
|
||||
value: "5"
|
||||
- name: API_SWAGGER_ENABLED
|
||||
value: "true"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /_meta/livez
|
||||
|
|
Loading…
Reference in New Issue