From 6f7fdad9441d0f783a1736689d32a1d390ba379d Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Fri, 2 Dec 2022 21:03:08 +0100 Subject: [PATCH] Fixes, refactor, a lot of things happen --- .env.dist | 8 +- Dockerfile | 25 ---- Dockerfile.builder | 15 ++ Dockerfile.target | 23 +++ Makefile | 19 +++ README.md | 4 +- deploy/image-build.sh | 39 +++++- src/cmd/main.go | 49 ------- src/cmd/server/main.go | 64 +++++++++ src/go.mod | 30 +++- src/go.sum | 162 +++++++++++++++++++++- src/internal/app/config/env.go | 2 +- src/internal/app/definition/auth.go | 1 + src/internal/app/definition/health.go | 5 + src/internal/app/handler/auth.go | 35 ----- src/internal/app/handler/error.go | 17 --- src/internal/app/handler/handler.go | 83 ----------- src/internal/app/handler/health_check.go | 42 ------ src/internal/app/handler/secret.go | 10 ++ src/internal/app/log.go | 12 +- src/internal/app/middleware/jwt.go | 37 +++++ src/internal/app/router.go | 23 --- src/internal/app/server.go | 85 ------------ src/internal/app/server/config.go | 22 +++ src/internal/app/server/health_handler.go | 12 ++ src/internal/app/server/login_handler.go | 24 ++++ src/internal/app/server/router.go | 30 ++++ src/internal/app/server/server.go | 111 +++++++++++++++ src/internal/app/service/auth.go | 97 +++---------- src/internal/app/service/jwt.go | 53 +++++++ 30 files changed, 685 insertions(+), 454 deletions(-) delete mode 100644 Dockerfile create mode 100644 Dockerfile.builder create mode 100644 Dockerfile.target create mode 100644 Makefile delete mode 100644 src/cmd/main.go create mode 100644 src/cmd/server/main.go create mode 100644 src/internal/app/definition/health.go delete mode 100644 src/internal/app/handler/auth.go delete mode 100644 src/internal/app/handler/handler.go delete mode 100644 src/internal/app/handler/health_check.go create mode 100644 src/internal/app/handler/secret.go create mode 100644 src/internal/app/middleware/jwt.go delete mode 100644 src/internal/app/router.go delete mode 100644 src/internal/app/server.go create mode 100644 src/internal/app/server/config.go create mode 100644 src/internal/app/server/health_handler.go create mode 100644 src/internal/app/server/login_handler.go create mode 100644 src/internal/app/server/router.go create mode 100644 src/internal/app/server/server.go create mode 100644 src/internal/app/service/jwt.go diff --git a/.env.dist b/.env.dist index e8fd4ed..c003f55 100644 --- a/.env.dist +++ b/.env.dist @@ -1,2 +1,6 @@ -SERVER_IP=0.0.0.0 -DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/egommerce +SERVER_ADDR=:80 +DATABASE_URL=postgres://postgres:12345678@postgres-db:5432/egommerce +MONGODB_URL=mongodb://mongodb:12345678@mongo-db:27017 +EVENTBUS_URL=amqp://guest:guest@api-eventbus:5672 + +JWT_SECRET_KEY=alaMaCotYnaTo34535647 diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 7035cbe..0000000 --- a/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -# Builder -FROM golang:alpine AS builder - -WORKDIR /go/src/app - -ARG MAIN_GO=cmd/main.go - -COPY src ./ - -RUN go mod download && \ - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o /go/bin/app $MAIN_GO - -# Destination image -FROM gcr.io/distroless/base-debian10 - -LABEL author="Piotr Biernat" -LABEL service="identity" -LABEL vendor="Egommerce" -LABEL version="1.0" - -COPY --from=builder /go/bin/app /app -COPY .env.dist /.env - -EXPOSE 8080 -ENTRYPOINT ["/app"] diff --git a/Dockerfile.builder b/Dockerfile.builder new file mode 100644 index 0000000..07582c5 --- /dev/null +++ b/Dockerfile.builder @@ -0,0 +1,15 @@ +# Builder +FROM golang:alpine + +ARG BIN_OUTPUT=/go/bin +ARG GO_SERVER=cmd/server/main.go +# ARG GO_WORKER=cmd/worker/main.go + +WORKDIR /go/src/app +COPY src ./ + +RUN export CGO_ENABLED=0 ; export GOOS=linux ; export GOARCH=amd64 && \ + go build -ldflags="-w -s" -o "$BIN_OUTPUT/server" $GO_SERVER + # && \ + # go build -ldflags="-w -s" -o "$BIN_OUTPUT/worker" $GO_WORKER + \ No newline at end of file diff --git a/Dockerfile.target b/Dockerfile.target new file mode 100644 index 0000000..3ad6fa6 --- /dev/null +++ b/Dockerfile.target @@ -0,0 +1,23 @@ +# Builder +ARG BUILDER_IMAGE="git.pbiernat.dev/egommerce/identity-builder:latest" +FROM ${BUILDER_IMAGE} AS builder + +# Destination image - server +# FROM gcr.io/distroless/base-debian10 +FROM alpine:3.17 + +ARG BIN_OUTPUT +ARG SVC_NAME +ARG SVC_VER + +LABEL dev.egommerce.image.author="Piotr Biernat" +LABEL dev.egommerce.image.service="identity-svc" +LABEL dev.egommerce.image.service=${SVC_NAME} +LABEL dev.egommerce.image.version=${SVC_VER} + +WORKDIR / +COPY --from=builder $BIN_OUTPUT /app +COPY .env.dist /.env + +EXPOSE 80 +ENTRYPOINT ["/app"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2d234f9 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +DEPLOY_DIR := ./deploy +SRC_DIR := ./src + +## DEPLOY PART +build-image-dev: + - sh ${DEPLOY_DIR}/image-build.sh dev + +build-image-prod: + - sh ${DEPLOY_DIR}/image-build.sh + +push-image-prod: + - sh ${DEPLOY_DIR}/image-push.sh + +# (GOLANG) APP PART +app-run: + - make -C ${SRC_DIR} run + +app-build: + - make -C ${SRC_DIR} build diff --git a/README.md b/README.md index fbfe855..011101a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Authentication & Authorization service Budowanie obrazu: -$ sh deploy/image-build.sh +$ sh deploy/image-build.sh [docker_tag] Opublikowanie obrazu: -$ sh deploy/image-push.sh +$ sh deploy/image-push.sh [docker_tag] diff --git a/deploy/image-build.sh b/deploy/image-build.sh index fed2034..e6ae076 100755 --- a/deploy/image-build.sh +++ b/deploy/image-build.sh @@ -1,6 +1,41 @@ #!/bin/sh # RUN IN REPO ROOT DIR !! -export IMAGE_NAME="git.pbiernat.dev/egommerce/identity-svc" +export IMAGE_PREFIX="git.pbiernat.dev/egommerce/identity" +export BUILDER_IMAGE="$IMAGE_PREFIX-builder:tmp" +export SERVER_IMAGE="$IMAGE_PREFIX-svc" +# export WORKER_IMAGE="$IMAGE_PREFIX-worker" -docker build --rm --cache-from "$IMAGE_NAME:latest" -t "$IMAGE_NAME:latest" . +TARGET=${1:-latest} + +[ ! -d \"src/vendor\" ] && sh -c "cd src; go mod vendor" + +export DOCKER_BUILDKIT=1 + +docker build -t "$BUILDER_IMAGE" -f Dockerfile.builder . && echo "Successfully tagged $BUILDER_IMAGE" + +echo "Building target $IMAGE_PREFIX images..." +if [ $TARGET = "latest" ] +then + # SERVER + docker build --build-arg SVC_NAME=identity-svc --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/server \ + --rm --build-arg BUILDER_IMAGE --cache-from "$SERVER_IMAGE:$TARGET" -t "$SERVER_IMAGE:$TARGET" \ + -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET" & + + # WORKER + # docker build --build-arg SVC_NAME=identity-worker --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/worker \ + # --rm --build-arg BUILDER_IMAGE --cache-from "$WORKER_IMAGE:$TARGET" -t "$WORKER_IMAGE:$TARGET" \ + # -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $WORKER_IMAGE:$TARGET" +else + # SERVER + docker build --build-arg SVC_NAME=identity-svc --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/server \ + --rm --build-arg BUILDER_IMAGE --no-cache -t "$SERVER_IMAGE:$TARGET" \ + -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET" & + + # WORKER + # docker build --build-arg SVC_NAME=identity-worker --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/worker \ + # --rm --build-arg BUILDER_IMAGE --no-cache -t "$WORKER_IMAGE:$TARGET" \ + # -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $WORKER_IMAGE:$TARGET" +fi + +echo "Done." diff --git a/src/cmd/main.go b/src/cmd/main.go deleted file mode 100644 index 9e19c20..0000000 --- a/src/cmd/main.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "context" - "net" - "os" - "os/signal" - "time" - - "git.pbiernat.dev/egommerce/identity-service/internal/app" - "git.pbiernat.dev/egommerce/identity-service/internal/app/config" - "git.pbiernat.dev/egommerce/identity-service/internal/app/database" - "git.pbiernat.dev/egommerce/identity-service/internal/app/handler" -) - -const ( - defHTTPIP = "0.0.0.0" - defHTTPPort = "8080" - defDbURL = "postgres://postgres:12345678@postgres_svc:5432/egommerce" -) - -func main() { - if config.ErrLoadingEnvs != nil { - app.Panicf("Error loading .env file") - } - - httpAddr := net.JoinHostPort(config.GetEnv("SERVER_IP", defHTTPIP), defHTTPPort) - dbConnStr := config.GetEnv("DATABASE_URL", defDbURL) - - dbc, err := database.Connect(dbConnStr) - if err != nil { - app.Panicf("Unable to connect to database: %v\n", err) - } - - env := &handler.Env{Addr: httpAddr, DB: dbc} - srv := app.NewServer(env) - - go srv.Start() - - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - <-c - - ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) - defer cancel() - - srv.Shutdown(ctx) - os.Exit(0) -} diff --git a/src/cmd/server/main.go b/src/cmd/server/main.go new file mode 100644 index 0000000..6287dea --- /dev/null +++ b/src/cmd/server/main.go @@ -0,0 +1,64 @@ +package main + +import ( + "log" + "os" + "strconv" + + "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" + "git.pbiernat.dev/egommerce/identity-service/internal/app/config" + "git.pbiernat.dev/egommerce/identity-service/internal/app/database" + "git.pbiernat.dev/egommerce/identity-service/internal/app/server" +) + +const ( + defAppName = "identity-svc" + defAppDomain = "identity-svc" + defNetAddr = ":80" + defLoggerAddr = "api-logger:24224" + defRegistryAddr = "api-registry:8500" + defDbURL = "postgres://postgres:12345678@postgres-db:5432/egommerce" + defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" + defEventBusURL = "amqp://guest:guest@api-eventbus:5672" + ebEventsExchange = "api-events" + ebEventsQueue = "identity-svc" +) + +func main() { + if config.ErrLoadingEnvs != nil { + log.Panicln("Error loading .env file", config.ErrLoadingEnvs) + } + + c := new(server.Config) + c.AppID, _ = os.Hostname() + c.AppName = config.GetEnv("APP_NAME", defAppName) + c.AppDomain = config.GetEnv("APP_DOMAIN", defAppDomain) + c.NetAddr = config.GetEnv("SERVER_ADDR", defNetAddr) + c.Port, _ = strconv.Atoi(c.NetAddr[1:]) + c.LoggerAddr = config.GetEnv("LOGGER_ADDR", defLoggerAddr) + c.RegistryAddr = config.GetEnv("REGISTRY_ADDR", defRegistryAddr) + c.DbURL = config.GetEnv("DATABASE_URL", defDbURL) + c.EventBusURL = config.GetEnv("EVENTBUS_URL", defEventBusURL) + c.EventBusExchange = ebEventsExchange + + logHost, logPort := fluentd.ParseAddr(c.LoggerAddr) + logger := fluentd.NewLogger(c.GetAppFullName(), logHost, logPort) + defer logger.Close() + + // db conn + dbConn, err := database.Connect(c.DbURL) + if err != nil { // fixme: add wait-for-db... + logger.Log("Failed to connect to Database server: %v\n", err) + os.Exit(1) + } + defer dbConn.Close() + + // start server + srv := server.NewServer(c, logger, dbConn /*, ebCh*/) + + forever := make(chan struct{}) + srv.StartWithGracefulShutdown(forever) + <-forever + + // os.Exit(1) +} diff --git a/src/go.mod b/src/go.mod index a267757..855f370 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,13 +3,28 @@ module git.pbiernat.dev/egommerce/identity-service go 1.18 require ( + git.pbiernat.dev/egommerce/go-api-pkg v0.0.101 + github.com/gofiber/fiber/v2 v2.40.1 + github.com/gofiber/jwt/v2 v2.2.7 github.com/golang-jwt/jwt v3.2.2+incompatible - github.com/gorilla/mux v1.8.0 github.com/jackc/pgx/v4 v4.17.2 github.com/joho/godotenv v1.4.0 + github.com/streadway/amqp v1.0.0 ) require ( + github.com/andybalholm/brotli v1.0.4 // indirect + github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect + github.com/fatih/color v1.9.0 // indirect + github.com/fluent/fluent-logger-golang v1.9.0 // indirect + github.com/golang-jwt/jwt/v4 v4.0.0 // indirect + github.com/hashicorp/consul/api v1.18.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.1 // indirect + github.com/hashicorp/go-hclog v0.12.0 // indirect + github.com/hashicorp/go-immutable-radix v1.0.0 // indirect + github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/serf v0.10.1 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgconn v1.13.0 // indirect github.com/jackc/pgio v1.0.0 // indirect @@ -18,6 +33,19 @@ require ( github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect github.com/jackc/pgtype v1.12.0 // indirect github.com/jackc/puddle v1.3.0 // indirect + github.com/klauspost/compress v1.15.9 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/philhofer/fwd v1.1.1 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/tinylib/msgp v1.1.6 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.41.0 // indirect + github.com/valyala/tcplisten v1.0.0 // indirect golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect + golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect golang.org/x/text v0.3.7 // indirect ) diff --git a/src/go.sum b/src/go.sum index c09ba18..d32c6f9 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,23 +1,89 @@ +git.pbiernat.dev/egommerce/go-api-pkg v0.0.101 h1:NZCFAAlC94+LcN1gjrENnWUHvpWgaNksyB2N4Fiy8C4= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.101/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fluent/fluent-logger-golang v1.9.0 h1:zUdY44CHX2oIUc7VTNZc+4m+ORuO/mldQDA7czhWXEg= +github.com/fluent/fluent-logger-golang v1.9.0/go.mod h1:2/HCT/jTy78yGyeNGQLGQsjF3zzzAuy6Xlk6FCMV5eU= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gofiber/fiber/v2 v2.17.0/go.mod h1:iftruuHGkRYGEXVISmdD7HTYWyfS2Bh+Dkfq4n/1Owg= +github.com/gofiber/fiber/v2 v2.40.1 h1:pc7n9VVpGIqNsvg9IPLQhyFEMJL8gCs1kneH5D1pIl4= +github.com/gofiber/fiber/v2 v2.40.1/go.mod h1:Gko04sLksnHbzLSRBFWPFdzM9Ws9pRxvvIaohJK1dsk= +github.com/gofiber/jwt/v2 v2.2.7 h1:MgXZV+ak+FiRVepD3btHBxWcyxlFzTDGXJv78dU1sIE= +github.com/gofiber/jwt/v2 v2.2.7/go.mod h1:yaOHLccYXJidk1HX/EiIdIL+Z1xmY2wnIv6hgViw384= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= 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-jwt/jwt/v4 v4.0.0 h1:RAqyYixv1p7uEnocuy8P1nru5wprCh/MH2BIlW5z5/o= +github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/hashicorp/consul/api v1.18.0 h1:R7PPNzTCeN6VuQNDwwhZWJvzCtGSrNpJqfb22h3yH9g= +github.com/hashicorp/consul/api v1.18.0/go.mod h1:owRRGJ9M5xReDC5nfT8FTJrNAPbT4NM6p/k+d03q2v4= +github.com/hashicorp/consul/sdk v0.13.0 h1:lce3nFlpv8humJL8rNrrGHYSKc3q+Kxfeg3Ii1m6ZWU= +github.com/hashicorp/consul/sdk v0.13.0/go.mod h1:0hs/l5fOVhJy/VdcoaNqUSi2AUs95eF5WKtv+EYIQqE= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= +github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= +github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= +github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= +github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -69,39 +135,86 @@ github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dv github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +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/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= 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 v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 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.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +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/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= +github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo= +github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -111,6 +224,16 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ 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/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw= +github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.26.0/go.mod h1:cmWIqlu99AO/RKcp1HWaViTqc57FswJOfYYdPJBl8BA= +github.com/valyala/fasthttp v1.41.0 h1:zeR0Z1my1wDHTRiamBCXVglQdbUwgb9uWG3k1HQz6jY= +github.com/valyala/fasthttp v1.41.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -127,23 +250,37 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= 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-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo= +golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -151,14 +288,26 @@ golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/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-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -171,19 +320,26 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= 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.v3 v3.0.0-20200313102051-9f266ea9e77c/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= diff --git a/src/internal/app/config/env.go b/src/internal/app/config/env.go index f08d8ff..9dbe349 100644 --- a/src/internal/app/config/env.go +++ b/src/internal/app/config/env.go @@ -12,7 +12,7 @@ func init() { ErrLoadingEnvs = godotenv.Load() } -func GetEnv(name, defVal string) string { +func GetEnv(name string, defVal string) string { // FIXME defVal and return types env := os.Getenv(name) if env == "" { return defVal diff --git a/src/internal/app/definition/auth.go b/src/internal/app/definition/auth.go index f32ca44..2516eeb 100644 --- a/src/internal/app/definition/auth.go +++ b/src/internal/app/definition/auth.go @@ -6,4 +6,5 @@ type AuthLoginRequest struct { } type AuthLoginResponse struct { + JWTToken string `json:"jwt_token"` } diff --git a/src/internal/app/definition/health.go b/src/internal/app/definition/health.go new file mode 100644 index 0000000..6920fca --- /dev/null +++ b/src/internal/app/definition/health.go @@ -0,0 +1,5 @@ +package definition + +type HealthResponse struct { + Status string `json:"status,omitempty"` +} diff --git a/src/internal/app/handler/auth.go b/src/internal/app/handler/auth.go deleted file mode 100644 index 57cf742..0000000 --- a/src/internal/app/handler/auth.go +++ /dev/null @@ -1,35 +0,0 @@ -package handler - -import ( - "net/http" - - def "git.pbiernat.dev/egommerce/identity-service/internal/app/definition" - "git.pbiernat.dev/egommerce/identity-service/internal/app/service" -) - -var AuthLoginHandler *Handler - -func init() { - AuthLoginHandler = &Handler{ - Handle: AuthLoginHandlerFunc, - Request: &def.AuthLoginRequest{}, - Response: &def.AuthLoginResponse{}, - } -} - -func AuthLoginHandlerFunc(h *Handler, w http.ResponseWriter) (interface{}, int, error) { - var req = h.Request.(*def.AuthLoginRequest) - // u := entity.TestUser - - token, err := service.AuthService.Login(req) - if err != nil { - return nil, http.StatusForbidden, err - } - - service.AuthService.SetCookie(w, service.AuthService.TokenCookieName, token) - // service.AuthService.SetCookie(w, service.AuthService.RefreshTokenCookieName, refreshTtoken) - - // log.Println("user:", u, "req:", token, "err:", err) - - return nil, http.StatusOK, nil -} diff --git a/src/internal/app/handler/error.go b/src/internal/app/handler/error.go index 576a84c..abeebd1 100644 --- a/src/internal/app/handler/error.go +++ b/src/internal/app/handler/error.go @@ -1,18 +1 @@ package handler - -import ( - "errors" - "net/http" -) - -type NotFoundHandler struct{} - -func (NotFoundHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - encodeResponse(w, &response{http.StatusNotFound, ""}, errors.New("Path "+r.RequestURI+" not found")) -} - -type MethodNotAllowedHandler struct{} - -func (MethodNotAllowedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - encodeResponse(w, &response{http.StatusMethodNotAllowed, ""}, errors.New("Method Not Allowed: "+r.Method)) -} diff --git a/src/internal/app/handler/handler.go b/src/internal/app/handler/handler.go deleted file mode 100644 index b5d192d..0000000 --- a/src/internal/app/handler/handler.go +++ /dev/null @@ -1,83 +0,0 @@ -package handler - -import ( - "bytes" - "encoding/json" - "io" - "log" - "net/http" - - def "git.pbiernat.dev/egommerce/identity-service/internal/app/definition" - "github.com/gorilla/mux" - "github.com/jackc/pgx/v4/pgxpool" -) - -type Env struct { - Addr string - DB *pgxpool.Pool -} - -type Handler struct { - *Env - Handle HandlerFunc - Request interface{} - Response interface{} - Params Set -} - -type HandlerFunc func(h *Handler, w http.ResponseWriter) (interface{}, int, error) - -type Set map[string]string - -type response struct { - Status int - Data interface{} -} - -func Init(e *Env, h *Handler) *Handler { - // return &Handler{e, h.Handle, h.Request, h.Response, Set{}} - h.Env = e - - return h -} - -func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if err := decodeRequestData(r, h.Request); err != nil { - log.Println("Decode request data error:", err.Error()) - - w.WriteHeader(http.StatusInternalServerError) - } - - h.Params = mux.Vars(r) - res, code, err := h.Handle(h, w) - - encodeResponse(w, &response{code, res}, err) -} - -func decodeRequestData(r *http.Request, v interface{}) error { - buf, _ := io.ReadAll(r.Body) - rdr := io.NopCloser(bytes.NewReader(buf)) - r.Body = io.NopCloser(bytes.NewReader(buf)) - - json.NewDecoder(rdr).Decode(&v) - - return nil -} - -func encodeResponse(w http.ResponseWriter, res *response, e error) { - if e != nil { - encodeError(w, res.Status, e) - return - } - - w.WriteHeader(res.Status) - if res.Data != nil { - json.NewEncoder(w).Encode(res.Data) - } -} - -func encodeError(w http.ResponseWriter, status int, e error) { - w.WriteHeader(status) - - json.NewEncoder(w).Encode(def.Error(e.Error())) -} diff --git a/src/internal/app/handler/health_check.go b/src/internal/app/handler/health_check.go deleted file mode 100644 index 7a63d39..0000000 --- a/src/internal/app/handler/health_check.go +++ /dev/null @@ -1,42 +0,0 @@ -package handler - -import ( - "net/http" -) - -var HealthCheckHandler *Handler - -func init() { - HealthCheckHandler = &Handler{ - Handle: HealthCheckHandlerFunc, - Request: &HealthCheckRequest{}, - Response: &HealthCheckResponse{}, - } -} - -type HealthCheckRequest struct { -} - -type HealthCheckResponse struct { - Status string `json:"status"` - Data *HealthCheckResponseBody `json:"data"` -} - -type HealthCheckResponseBody struct { - Message string `json:"message,omitempty"` - Status string `json:"status,omitempty"` -} - -func HealthCheckHandlerFunc(_ *Handler, w http.ResponseWriter) (interface{}, int, error) { - return &HealthCheckResponseBody{ - Message: "This is welcome health message. Everything seems to be alright ;)", - Status: "OK", - }, http.StatusOK, nil - - // return &HealthCheckResponse{ - // Status: http.StatusText(http.StatusOK), - // Data: &HealthCheckResponseBody{ - // Message: "This is welcome health message. Everything seems to be alright ;)", - // }, - // }, http.StatusOK, nil -} diff --git a/src/internal/app/handler/secret.go b/src/internal/app/handler/secret.go new file mode 100644 index 0000000..1d5c12e --- /dev/null +++ b/src/internal/app/handler/secret.go @@ -0,0 +1,10 @@ +package handler + +import ( + "github.com/gofiber/fiber/v2" +) + +func SecretHandler(c *fiber.Ctx) error { + + return nil +} diff --git a/src/internal/app/log.go b/src/internal/app/log.go index f8c39ea..fa33d99 100644 --- a/src/internal/app/log.go +++ b/src/internal/app/log.go @@ -1,16 +1,20 @@ package app -import "log" +import ( + "log" +) + +const AppName = "identity-svc" func Panic(v ...any) { - log.Panicln(Name+":", v) + log.Panicln(AppName+":", v) } func Panicf(format string, v ...any) { - log.Panicf(Name+": "+format, v...) + log.Panicf(AppName+": "+format, v...) } func Panicln(v ...any) { - v = append([]any{Name + ":"}, v...) + v = append([]any{AppName + ":"}, v...) log.Panicln(v...) } diff --git a/src/internal/app/middleware/jwt.go b/src/internal/app/middleware/jwt.go new file mode 100644 index 0000000..1c62921 --- /dev/null +++ b/src/internal/app/middleware/jwt.go @@ -0,0 +1,37 @@ +package middleware + +import ( + "os" + + "github.com/gofiber/fiber/v2" + jwtMiddleware "github.com/gofiber/jwt/v2" +) + +// JWTProtected func for specify routes group with JWT authentication. +// See: https://github.com/gofiber/jwt +func JWTProtected() func(*fiber.Ctx) error { + // Create config for JWT authentication middleware. + config := jwtMiddleware.Config{ + SigningKey: []byte(os.Getenv("JWT_SECRET_KEY")), + ContextKey: "jwt", // used in private routes + ErrorHandler: jwtError, + } + + return jwtMiddleware.New(config) +} + +func jwtError(c *fiber.Ctx, err error) error { + // Return status 400 Bad Request and failed authentication error. + if err.Error() == "Missing or malformed JWT" { + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ + "error": true, + "msg": err.Error(), + }) + } + + // Return status 401 Unauthorized and failed authentication error. + return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ + "error": true, + "msg": err.Error(), + }) +} diff --git a/src/internal/app/router.go b/src/internal/app/router.go deleted file mode 100644 index f97e2e6..0000000 --- a/src/internal/app/router.go +++ /dev/null @@ -1,23 +0,0 @@ -package app - -import ( - "net/http" - - "git.pbiernat.dev/egommerce/identity-service/internal/app/handler" - "github.com/gorilla/mux" -) - -func SetupRouter(env *handler.Env) *mux.Router { - r := mux.NewRouter() - r.NotFoundHandler = &handler.NotFoundHandler{} - r.MethodNotAllowedHandler = &handler.MethodNotAllowedHandler{} - - r.Use(PrepareHeadersMiddleware) - r.Use(ValidateJsonBodyMiddleware) // probably not needed - r.Use(LoggingMiddleware) - - r.Handle("/health", handler.Init(env, handler.HealthCheckHandler)).Methods(http.MethodGet) - r.Handle("/login", handler.Init(env, handler.AuthLoginHandler)).Methods(http.MethodPost) - - return r -} diff --git a/src/internal/app/server.go b/src/internal/app/server.go deleted file mode 100644 index cff4bc2..0000000 --- a/src/internal/app/server.go +++ /dev/null @@ -1,85 +0,0 @@ -package app - -import ( - "bytes" - "encoding/json" - "io" - "log" - "net" - "net/http" - "os" - "strconv" - "time" - - def "git.pbiernat.dev/egommerce/identity-service/internal/app/definition" - "git.pbiernat.dev/egommerce/identity-service/internal/app/handler" -) - -const Name = "REST API Service" - -type Server struct { - *http.Server -} - -func NewServer(env *handler.Env) *Server { - return &Server{ - &http.Server{ - Handler: SetupRouter(env), - Addr: env.Addr, - WriteTimeout: 15 * time.Second, - ReadTimeout: 15 * time.Second, - IdleTimeout: 60 * time.Second, - }, - } -} - -func (s *Server) Start() { - if os.Getenv("LISTEN_PID") == strconv.Itoa(os.Getpid()) { - // systemd run - f := os.NewFile(3, "from systemd") - l, err := net.FileListener(f) - if err != nil { - log.Fatalln(err) - } - - log.Println("Server listening on " + l.Addr().String()) - s.Serve(l) - } else { - - log.Println("Server listening on " + s.Addr) - log.Fatalln(s.ListenAndServe()) - } -} - -func PrepareHeadersMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=utf-8") - w.Header().Set("Connection", "keep-alive") - w.Header().Set("Keep-Alive", "timeout=5") - - next.ServeHTTP(w, r) - }) -} - -func ValidateJsonBodyMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - buf, _ := io.ReadAll(r.Body) - r.Body = io.NopCloser(bytes.NewReader(buf)) // rollack *Request to original state - - if len(buf) > 0 && !json.Valid(buf) { - w.WriteHeader(http.StatusBadRequest) - json.NewEncoder(w).Encode(def.Error("Unable to parse JSON: " + string(buf))) - - return - } - - next.ServeHTTP(w, r) - }) -} - -func LoggingMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - log.Println("Request: " + r.RequestURI + " remote: " + r.RemoteAddr + " via: " + r.UserAgent()) - next.ServeHTTP(w, r) - }) -} diff --git a/src/internal/app/server/config.go b/src/internal/app/server/config.go new file mode 100644 index 0000000..9bec52b --- /dev/null +++ b/src/internal/app/server/config.go @@ -0,0 +1,22 @@ +package server + +import "fmt" + +type Config struct { + AppID string + AppName string + AppDomain string + NetAddr string + Port int + LoggerAddr string + RegistryAddr string + DbURL string + MongoDbUrl string + EventBusURL string + EventBusExchange string + EventBusQueue string +} + +func (c *Config) GetAppFullName() string { + return fmt.Sprintf("%s_%s", c.AppName, c.AppID) +} diff --git a/src/internal/app/server/health_handler.go b/src/internal/app/server/health_handler.go new file mode 100644 index 0000000..858ed19 --- /dev/null +++ b/src/internal/app/server/health_handler.go @@ -0,0 +1,12 @@ +package server + +import ( + def "git.pbiernat.dev/egommerce/identity-service/internal/app/definition" + "github.com/gofiber/fiber/v2" +) + +func (s *Server) HealthHandler(c *fiber.Ctx) error { + return c.JSON(&def.HealthResponse{ + Status: "OK", + }) +} diff --git a/src/internal/app/server/login_handler.go b/src/internal/app/server/login_handler.go new file mode 100644 index 0000000..ee1f500 --- /dev/null +++ b/src/internal/app/server/login_handler.go @@ -0,0 +1,24 @@ +package server + +import ( + def "git.pbiernat.dev/egommerce/identity-service/internal/app/definition" + "git.pbiernat.dev/egommerce/identity-service/internal/app/service" + "github.com/gofiber/fiber/v2" +) + +func (s *Server) LoginHandler(c *fiber.Ctx) error { + data := new(def.AuthLoginRequest) + if err := c.BodyParser(data); err != nil { + return err + } + + token, err := service.AuthService.Login(data.Username, data.Password) + if err != nil { + return fiber.NewError(fiber.StatusUnauthorized) + } + + cookie := service.AuthService.Cookie("auth_token", token) + c.Cookie(cookie) + + return c.JSON(&def.AuthLoginResponse{JWTToken: token}) +} diff --git a/src/internal/app/server/router.go b/src/internal/app/server/router.go new file mode 100644 index 0000000..6aaf4cd --- /dev/null +++ b/src/internal/app/server/router.go @@ -0,0 +1,30 @@ +package server + +import ( + "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" + "github.com/gofiber/fiber/v2" +) + +func SetupRoutes(s *Server) { + s.App.Get("/health", s.HealthHandler) + + api := s.App.Group("/api") + v1 := api.Group("/v1") + v1.Post("/login", s.LoginHandler) +} + +func SetupMiddlewares(s *Server) { + s.App.Use(LoggingMiddleware(s.log)) +} + +// Middlewares +func LoggingMiddleware(log *fluentd.Logger) func(c *fiber.Ctx) error { + return func(c *fiber.Ctx) error { + log.Log("Request: %s, remote: %s, via: %s", + c.Request().URI().String(), + c.Context().RemoteIP().String(), + string(c.Context().UserAgent())) + + return c.Next() + } +} diff --git a/src/internal/app/server/server.go b/src/internal/app/server/server.go new file mode 100644 index 0000000..03ff34e --- /dev/null +++ b/src/internal/app/server/server.go @@ -0,0 +1,111 @@ +package server + +import ( + "os" + "os/signal" + "syscall" + "time" + + "github.com/gofiber/fiber/v2" + "github.com/jackc/pgx/v4/pgxpool" + + discovery "git.pbiernat.dev/egommerce/go-api-pkg/consul" + "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" +) + +type Server struct { + *fiber.App + log *fluentd.Logger + db *pgxpool.Pool + // ebCh *amqp.Channel + discovery *discovery.Service + name string + addr string +} + +type Headers struct { + RequestID string `reqHeader:"x-request-id"` +} + +func NewServer(conf *Config, logger *fluentd.Logger, db *pgxpool.Pool /*, ebCh *amqp.Channel*/) *Server { + logger.Log("API_ID: %s", conf.AppID) + discovery, err := discovery.NewService(conf.RegistryAddr, conf.AppID, conf.AppName, conf.AppID, conf.AppDomain, conf.Port) + if err != nil { + logger.Log("Error connecting to %s: %v", conf.RegistryAddr, err) + } + + logger.Log("Registering service with name: %s, address: %s", discovery.Name, discovery.Address) + err = discovery.Register() + if err != nil { + logger.Log("register error: %v", err) + } + + cnf := fiber.Config{ + AppName: conf.AppName, + ServerHeader: conf.AppName, + ReadTimeout: time.Millisecond * 50, + WriteTimeout: time.Millisecond * 50, + IdleTimeout: time.Millisecond * 50, + } + s := &Server{ + fiber.New(cnf), + logger, + db, + /*ebCh,*/ + discovery, + conf.AppName, + conf.NetAddr, + } + + SetupMiddlewares(s) + SetupRoutes(s) + + return s +} + +func (s *Server) Start() { + err := s.Listen(s.addr) + s.log.Log("Starting error: %v", err) +} + +func (s *Server) StartWithGracefulShutdown(forever chan struct{}) { + go func() { + sigint := make(chan os.Signal, 1) + signal.Notify(sigint, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + <-sigint + + if err := s.gracefulShutdown(); err != nil { + s.log.Log("Server is not shutting down! Reason: %v", err) + } + + close(forever) + }() + + if err := s.Listen(s.addr); err != nil { + s.log.Log("Server is not running! Reason: %v", err) + } + + <-forever +} + +// GetRequestID Return current requets ID - works only when fiber context are running +func (s *Server) GetRequestID(c *fiber.Ctx) (string, error) { + var hdr = new(Headers) + if err := c.ReqHeaderParser(hdr); err != nil { + return "", err + } + + return hdr.RequestID, nil +} + +func (s *Server) gracefulShutdown() error { + s.log.Log("Server is going down...") + s.log.Log("Unregistering service: %s", s.discovery.GetID()) + s.discovery.Unregister() + + // s.ebCh.Close() + s.db.Close() + s.log.Close() + + return s.Shutdown() +} diff --git a/src/internal/app/service/auth.go b/src/internal/app/service/auth.go index 9a817ed..9b33609 100644 --- a/src/internal/app/service/auth.go +++ b/src/internal/app/service/auth.go @@ -1,113 +1,50 @@ package service import ( - "encoding/json" "errors" - "fmt" - "log" - "net/http" "strconv" - "time" "git.pbiernat.dev/egommerce/identity-service/internal/app/config" - def "git.pbiernat.dev/egommerce/identity-service/internal/app/definition" - "github.com/golang-jwt/jwt" + "github.com/gofiber/fiber/v2" ) var ( AuthService *Auth + JWTService *JWT - ErrUserNotFound = errors.New("user not found") - ErrTokenError = errors.New("failed to generate JWT token") + ErrLoginIncorrect = errors.New("login incorrect") ) func init() { - expire, _ := strconv.Atoi(config.GetEnv("AUTH_TOKEN_EXPIRE_TIME", "5")) - secret := []byte(config.GetEnv("AUTH_SECRET_HMAC", "B413IlIv9nKQfsMCXTE0Cteo4yHgUEfqaLfjg73sNlh")) - - AuthService = &Auth{expire, "jwt_token", "jwt_token_refresh", secret} + cookieExpireTime, _ := strconv.Atoi(config.GetEnv("AUTH_COOKIE_EXPIRE_TIME", "5")) + AuthService = &Auth{"jwt_token", "jwt_token_refresh", cookieExpireTime} } type Auth struct { - ExpireTime int // token expire time in minutes TokenCookieName string RefreshTokenCookieName string - - secret []byte // signing key + cookieExpireTime int } -func (a *Auth) Login(r *def.AuthLoginRequest) (string, error) { - if r.Username == "admin" && r.Password == "secret" { - token, err := a.createToken() +func (a *Auth) Login(login, pass string) (string, error) { + if login == "admin" && pass == "secret" { + token, err := JWTService.CreateToken() if err != nil { - return "", ErrTokenError + return "", err } return token, nil } - return "", ErrUserNotFound + return "", ErrLoginIncorrect } -// SetCookie appends cookie header to response -func (a *Auth) SetCookie(w http.ResponseWriter, name, token string) { - c := &http.Cookie{ +// Cookie create fiber.Cookie struct +func (a *Auth) Cookie(name, value string) *fiber.Cookie { + return &fiber.Cookie{ Name: name, - Value: token, - MaxAge: a.ExpireTime * 60, - Path: "/", + Value: value, + MaxAge: a.cookieExpireTime * 300, // FIXME: env/config + Path: "/", // FIXME: env/config } - http.SetCookie(w, c) -} - -func (a Auth) createToken() (string, error) { - // log.Println("now:", time.Now().Unix()) - // log.Println("expire at:", time.Now().Add(time.Duration(a.ExpireTime)*time.Minute).Unix()) - claims := &jwt.StandardClaims{ - ExpiresAt: time.Now().Add(time.Duration(a.ExpireTime) * time.Minute).Unix(), - } - - token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) - return token.SignedString(a.secret) -} - -func (a *Auth) validateToken(tokenStr string) error { - token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) { - // Don't forget to validate the alg is what you expect: - if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { - return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) - } - - // hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key") - return a.secret, nil - }) - - if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { - log.Println(claims) - } else { - return err - } - - return nil -} - -func (a Auth) ValidateUserTokenMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - cToken, err := r.Cookie(a.TokenCookieName) - if err != nil { - w.WriteHeader(http.StatusUnauthorized) - json.NewEncoder(w).Encode(def.Error("Missing JWT Token cookie")) - - return - } - - if err := a.validateToken(cToken.Value); err != nil { - w.WriteHeader(http.StatusUnauthorized) - json.NewEncoder(w).Encode(def.Error(err.Error())) - - return - } - - next.ServeHTTP(w, r) - }) } diff --git a/src/internal/app/service/jwt.go b/src/internal/app/service/jwt.go new file mode 100644 index 0000000..f77a10d --- /dev/null +++ b/src/internal/app/service/jwt.go @@ -0,0 +1,53 @@ +package service + +import ( + "fmt" + "strconv" + "time" + + "git.pbiernat.dev/egommerce/identity-service/internal/app/config" + "github.com/golang-jwt/jwt" +) + +var ( + tokenExpireTime int + tokenSecret []byte +) + +func init() { + tokenExpireTime, _ = strconv.Atoi(config.GetEnv("JWT_TOKEN_EXPIRE_TIME", "5")) + tokenSecret = []byte(config.GetEnv("JWT_SECRET_KEY", "B413IlIv9nKQfsMCXTE0Cteo4yHgUEfqaLfjg73sNlh")) // FIXME env: JWT_SECRET_KEY !!! + + JWTService = &JWT{tokenExpireTime, tokenSecret} +} + +type JWT struct { + tokenExpireTime int + tokenSecret []byte +} + +func (s *JWT) CreateToken() (string, error) { + claims := &jwt.StandardClaims{ + ExpiresAt: time.Now().Add(time.Duration(s.tokenExpireTime) * time.Minute).Unix(), + } + + token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + return token.SignedString(s.tokenSecret) +} + +func (s *JWT) ValidateToken(tokenStr string) error { + token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) { + // Don't forget to validate the alg is what you expect: + if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) + } + + return s.tokenSecret, nil + }) + + if _, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { + return nil + } + + return err +}