dev into clean script

This commit is contained in:
Pasha 2024-11-21 11:52:19 +03:00
commit a420869004
40 changed files with 888 additions and 372 deletions

2
.gitignore vendored

@ -1,3 +1,3 @@
.idea .idea
test.env main
.vscode .vscode

@ -3,10 +3,16 @@ include:
file: "/templates/docker/build-template.gitlab-ci.yml" file: "/templates/docker/build-template.gitlab-ci.yml"
- project: "devops/pena-continuous-integration" - project: "devops/pena-continuous-integration"
file: "/templates/docker/deploy-template.gitlab-ci.yml" file: "/templates/docker/deploy-template.gitlab-ci.yml"
- project: "devops/pena-continuous-integration"
file: "/templates/docker/golint.gitlab-ci.yml"
stages: stages:
- lint
- build - build
- deploy - deploy
lint:
extends: .golint_template
build-app: build-app:
extends: .build_template extends: .build_template

21
.golangci.yml Normal file

@ -0,0 +1,21 @@
run:
timeout: 5m
skip-files:
- \.pb\.go$
- .pb.go
- \.pb\.validate\.go$
- \.pb\.gw\.go$
- .pb.gw.go
- \.gen\.go$
skip-dirs:
- mocks
linters:
disable-all: true
enable:
- errcheck
linter-settings:
errcheck:
exclude-functions:
- (io.Closer).Close

5
CHANGELOG.md Normal file

@ -0,0 +1,5 @@
#v1.0.1
- убрали egrule файл из модели, потому что изначально он был создан из недопонимания и являлся лишним
#v1.0.0

10
Taskfile.dist.yml Normal file

@ -0,0 +1,10 @@
version: "3"
tasks:
update-linter:
cmds:
- go get -u penahub.gitlab.yandexcloud.net/devops/linters/golang.git
lint:
cmds:
- task: update-linter
- cmd: golangci-lint run -v -c $(go list -f '{{"{{"}}.Dir{{"}}"}}' -m penahub.gitlab.yandexcloud.net/devops/linters/golang.git)/.golangci.yml

@ -1,16 +1,38 @@
package main package main
import ( import (
"go.uber.org/zap"
"log" "log"
"os"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/app" "penahub.gitlab.yandexcloud.net/backend/verification/internal/app"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/config" "penahub.gitlab.yandexcloud.net/backend/verification/internal/config"
_ "penahub.gitlab.yandexcloud.net/devops/linters/golang.git/pkg/dummy"
"time"
) )
var (
commit string = os.Getenv("COMMIT")
buildTime string = os.Getenv("BUILD_TIME")
version string = os.Getenv("VERSION")
)
// $env:COMMIT=$(git rev-parse --short HEAD); $env:BUILD_TIME=$(Get-Date -UFormat "%Y-%m-%dT%H:%M:%SZ"); $env:VERSION=$(git describe --tags); go run cmd/verification/main.go
func main() { func main() {
ptime, err := time.Parse(time.RFC3339, buildTime)
if err != nil {
log.Println("Error parsing build time:", zap.Error(err))
ptime = time.Now()
}
cfg, err := config.NewConfig("staging.env") cfg, err := config.NewConfig("staging.env")
if err != nil { if err != nil {
log.Fatal("can't load config: ", err.Error()) log.Fatal("can't load config: ", err.Error())
} }
app.Run(cfg) app.Run(cfg, app.Build{
Commit: commit,
Version: version,
BuildTime: ptime.Unix(),
})
} }

@ -1,28 +1,36 @@
version: "3"
services: services:
verification: verificationv1.0.0:
container_name: verification_service container_name: verification_servicev1.0.0
restart: unless-stopped restart: unless-stopped
image: $CI_REGISTRY_IMAGE/main:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID image: $CI_REGISTRY_IMAGE/main:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
hostname: verification_service hostname: verification_servicev1.0.0
ports: ports:
- 10.8.0.8:7035:7035 - 10.8.0.8:7037:7035
- 10.8.0.8:7038:7036
environment: environment:
MONGO_URI: mongodb://$MONGO_USER-prod:$MONGO_PASSWORD@10.8.0.8:27017/?authSource=verification MONGO_URI: mongodb://$MONGO_USER-prod:$MONGO_PASSWORD@10.8.0.8:27017/?authSource=verification
PENADISK_URL: $PENADISK_URL PENADISK_URL: $PENADISK_URL
TELEGRAM_TOKEN: $TELEGRAM_TOKEN TELEGRAM_TOKEN: $TELEGRAM_TOKEN
TELEGRAM_CHANNEL_ID: -1001940097056 TELEGRAM_CHANNEL_ID: -1001940097056
S3_ENDPOINT: $S3_ENDPOINT S3_ENDPOINT: s3.timeweb.cloud
S3_ACCESS_KEY_ID: $S3_ACCESS_KEY_ID S3_ACCESS_KEY_ID: 5CV77KVDUU9H0II9R24M
S3_SECRET_KEY: $S3_SECRET_KEY S3_SECRET_KEY: 0W0m8DyvdAKRJnsAy6mB5zndQ7RouJBLhqhtThcu
JWT_SECRET: $JWT_SECRET JWT_SECRET: $JWT_SECRET
HTTP_ADDRESS: ":7035" HTTP_ADDRESS_USER: ":7035"
HTTP_ADDRESS_ADMIN: ":7036"
MONGO_HOST: "10.8.0.8" MONGO_HOST: "10.8.0.8"
MONGO_PORT: "27017" MONGO_PORT: "27017"
MONGO_USER: $MONGO_USER-prod MONGO_USER: $MONGO_USER-prod
MONGO_PASSWORD: $MONGO_PASSWORD MONGO_PASSWORD: $MONGO_PASSWORD
MONGO_AUTH: "verification" MONGO_AUTH: "verification"
MONGO_DATABASE_NAME: "verification" MONGO_DATABASE_NAME: "verification"
CUSTOMER_SVC_ADDRESS: "10.8.0.8:8065" CUSTOMER_SVC_ADDRESS: "http://10.8.0.8:9066"
STAGING_URL: "https://admin.pena" STAGING_URL: "https://admin.pena"
S3_FOLDER: verification
S3_FILE_URL: https://3c580be9-cf31f296-d055-49cf-b39e-30c7959dc17b.s3.timeweb.cloud
CUSTOMER_RPC_HOST: 10.8.0.8:9066
TRASH_LOG_HOST: 10.8.0.15:7113
MODULE_LOGGER: production-verification
tty: true tty: true

@ -1,28 +1,36 @@
version: "3"
services: services:
verification: verificationv1.0.0:
container_name: verification_service container_name: verification_servicev1.0.0
restart: unless-stopped restart: unless-stopped
image: $CI_REGISTRY_IMAGE/staging:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID image: $CI_REGISTRY_IMAGE/staging:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
hostname: verification_service hostname: verification_servicev1.0.0
ports: ports:
- 10.8.0.6:7035:7035 - 10.8.0.6:7036:7035
- 10.8.0.6:7037:7036
environment: environment:
MONGO_URI: mongodb://$MONGO_USER:$MONGO_PASSWORD@10.8.0.6:27017/?authSource=verification MONGO_URI: mongodb://$MONGO_USER:$MONGO_PASSWORD@10.8.0.6:27017/?authSource=verification
PENADISK_URL: $PENADISK_URL PENADISK_URL: $PENADISK_URL
TELEGRAM_TOKEN: $TELEGRAM_TOKEN TELEGRAM_TOKEN: $TELEGRAM_TOKEN
TELEGRAM_CHANNEL_ID: $TELEGRAM_CHANNEL_ID TELEGRAM_CHANNEL_ID: $TELEGRAM_CHANNEL_ID
S3_ENDPOINT: $S3_ENDPOINT S3_ENDPOINT: s3.timeweb.cloud
S3_ACCESS_KEY_ID: $S3_ACCESS_KEY_ID S3_ACCESS_KEY_ID: 5CV77KVDUU9H0II9R24M
S3_SECRET_KEY: $S3_SECRET_KEY S3_SECRET_KEY: 0W0m8DyvdAKRJnsAy6mB5zndQ7RouJBLhqhtThcu
JWT_SECRET: $JWT_SECRET JWT_SECRET: $JWT_SECRET
HTTP_ADDRESS: ":7035" HTTP_ADDRESS_USER: ":7035"
HTTP_ADDRESS_ADMIN: ":7036"
MONGO_HOST: "10.8.0.6" MONGO_HOST: "10.8.0.6"
MONGO_PORT: "27017" MONGO_PORT: "27017"
MONGO_USER: $MONGO_USER MONGO_USER: $MONGO_USER
MONGO_PASSWORD: $MONGO_PASSWORD MONGO_PASSWORD: $MONGO_PASSWORD
MONGO_AUTH: "verification" MONGO_AUTH: "verification"
MONGO_DATABASE_NAME: "verification" MONGO_DATABASE_NAME: "verification"
CUSTOMER_SVC_ADDRESS: "10.8.0.6:8065" CUSTOMER_SVC_ADDRESS: "http://10.8.0.6:9065"
STAGING_URL: "https://sadmin.pena" STAGING_URL: "https://sadmin.pena"
S3_FOLDER: verification
S3_FILE_URL: https://3c580be9-cf31f296-d055-49cf-b39e-30c7959dc17b.s3.timeweb.cloud
CUSTOMER_RPC_HOST: 10.8.0.6:9060
TRASH_LOG_HOST: 10.8.0.15:7113
MODULE_LOGGER: staging-verification
tty: true tty: true

@ -59,9 +59,6 @@ paths:
rule: rule:
type: string type: string
format: base64 format: base64
egrule:
type: string
format: base64
certificate: certificate:
type: string type: string
description: только для status == nko description: только для status == nko
@ -120,9 +117,6 @@ paths:
rule: rule:
type: string type: string
format: base64 format: base64
egrule:
type: string
format: base64
certificate: certificate:
type: string type: string
description: только для status == nko description: только для status == nko

59
go.mod

@ -1,40 +1,50 @@
module penahub.gitlab.yandexcloud.net/backend/verification module penahub.gitlab.yandexcloud.net/backend/verification
go 1.21 go 1.22.0
toolchain go1.21.4 toolchain go1.22.2
require ( require (
github.com/caarlos0/env/v8 v8.0.0 github.com/caarlos0/env/v8 v8.0.0
github.com/go-playground/validator/v10 v10.14.1 github.com/go-playground/validator/v10 v10.14.1
github.com/gofiber/contrib/fiberzap v1.0.2 github.com/gofiber/contrib/fiberzap v1.0.2
github.com/gofiber/fiber/v2 v2.51.0 github.com/gofiber/fiber/v2 v2.52.1
github.com/joho/godotenv v1.5.1 github.com/joho/godotenv v1.5.1
github.com/minio/minio-go/v7 v7.0.56 github.com/minio/minio-go/v7 v7.0.56
go.mongodb.org/mongo-driver v1.13.1 github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf
go.uber.org/zap v1.24.0 go.mongodb.org/mongo-driver v1.14.0
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240202120244-c4ef330cfe5d go.uber.org/zap v1.27.0
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240607202348-efe5f2bf3e8c
penahub.gitlab.yandexcloud.net/devops/linters/golang.git v0.0.0-20240828181923-80f1728efccc
penahub.gitlab.yandexcloud.net/external/trashlog.git v0.1.2-0.20240607135420-4279d2c37763
penahub.gitlab.yandexcloud.net/pena-services/customer v1.0.1-0.20240608222239-5c78187bf014
) )
require ( require (
github.com/kr/pretty v0.1.0 // indirect github.com/ClickHouse/clickhouse-go v1.5.4 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/skeris/appInit v1.0.2 // indirect
go.etcd.io/bbolt v1.3.10 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
google.golang.org/grpc v1.64.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/tucnak/telebot.v2 v2.5.0 // indirect
) )
require ( require (
github.com/andybalholm/brotli v1.0.5 // indirect github.com/andybalholm/brotli v1.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/dustin/go-humanize v1.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
github.com/golang/snappy v0.0.1 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/go-cmp v0.5.8 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/google/uuid v1.4.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/compress v1.17.7 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/leodido/go-urn v1.2.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
@ -44,26 +54,25 @@ require (
github.com/minio/sha256-simd v1.0.1 // indirect github.com/minio/sha256-simd v1.0.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect github.com/montanaflynn/stats v0.7.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.3 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/rs/xid v1.5.0 // indirect github.com/rs/xid v1.5.0 // indirect
github.com/sirupsen/logrus v1.9.2 // indirect github.com/sirupsen/logrus v1.9.2 // indirect
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.50.0 github.com/valyala/fasthttp v1.52.0
github.com/valyala/tcplisten v1.0.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect
go.uber.org/multierr v1.8.0 // indirect golang.org/x/crypto v0.24.0 // indirect
golang.org/x/crypto v0.9.0 // indirect golang.org/x/net v0.26.0 // indirect
golang.org/x/net v0.10.0 // indirect golang.org/x/sync v0.7.0 // indirect
golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.21.0 // indirect
golang.org/x/sys v0.14.0 // indirect golang.org/x/text v0.16.0 // indirect
golang.org/x/text v0.9.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

180
go.sum

@ -1,9 +1,14 @@
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk=
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
github.com/caarlos0/env/v8 v8.0.0 h1:POhxHhSpuxrLMIdvTGARuZqR4Jjm8AYmoi/JKlcScs0= github.com/caarlos0/env/v8 v8.0.0 h1:POhxHhSpuxrLMIdvTGARuZqR4Jjm8AYmoi/JKlcScs0=
github.com/caarlos0/env/v8 v8.0.0/go.mod h1:7K4wMY9bH0esiXSSHlfHLX5xKGQMnkH5Fk4TDSSSzfo= github.com/caarlos0/env/v8 v8.0.0/go.mod h1:7K4wMY9bH0esiXSSHlfHLX5xKGQMnkH5Fk4TDSSSzfo=
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -11,6 +16,10 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
@ -21,37 +30,42 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k= github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k=
github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc=
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=
github.com/gofiber/contrib/fiberzap v1.0.2 h1:EQwhggtszVfIdBeXxN9Xrmld71es34Ufs+ef8VMqZxc= github.com/gofiber/contrib/fiberzap v1.0.2 h1:EQwhggtszVfIdBeXxN9Xrmld71es34Ufs+ef8VMqZxc=
github.com/gofiber/contrib/fiberzap v1.0.2/go.mod h1:jGO8BHU4gRI9U0JtM6zj2CIhYfgVmW5JxziN8NTgVwE= github.com/gofiber/contrib/fiberzap v1.0.2/go.mod h1:jGO8BHU4gRI9U0JtM6zj2CIhYfgVmW5JxziN8NTgVwE=
github.com/gofiber/fiber/v2 v2.51.0 h1:JNACcZy5e2tGApWB2QrRpenTWn0fq0hkFm6k0C86gKQ= github.com/gofiber/fiber/v2 v2.52.1 h1:1RoU2NS+b98o1L77sdl5mboGPiW+0Ypsi5oLmcYlgHI=
github.com/gofiber/fiber/v2 v2.51.0/go.mod h1:xaQRZQJGqnKOQnbQw+ltvku3/h8QxvNi8o6JiJ7Ll0U= github.com/gofiber/fiber/v2 v2.52.1/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 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/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 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-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
@ -59,6 +73,7 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.56 h1:pkZplIEHu8vinjkmhsexcXpWth2tjVLphrTZx6fBVZY= github.com/minio/minio-go/v7 v7.0.56 h1:pkZplIEHu8vinjkmhsexcXpWth2tjVLphrTZx6fBVZY=
@ -70,33 +85,55 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.16.0 h1:NBrNLB37exjJLxXtFOktx6CISBdS1aF8+7MwKlTV8U4=
github.com/onsi/ginkgo v1.16.0/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug=
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pioz/faker v1.7.3 h1:Tez8Emuq0UN+/d6mo3a9m/9ZZ/zdfJk0c5RtRatrceM=
github.com/pioz/faker v1.7.3/go.mod h1:xSpay5w/oz1a6+ww0M3vfpe40pSIykeUPeWEc3TvVlc=
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 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y= github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y=
github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/skeris/appInit v1.0.2 h1:Hr4KbXYd6kolTVq4cXGqDpgnpmaauiOiKizA1+Ep4KQ=
github.com/skeris/appInit v1.0.2/go.mod h1:4ElEeXWVGzU3dlYq/eMWJ/U5hd+LKisc1z3+ySh1XmY=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 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.7.0/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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33 h1:N9f/Q+2Ssa+yDcbfaoLTYvXmdeyUUxsJKdPUVsjSmiA=
github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33/go.mod h1:rpcH99JknBh8seZmlOlUg51gasZH6QH34oXNsIwYT6E=
github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf h1:TJJm6KcBssmbWzplF5lzixXl1RBAi/ViPs1GaSOkhwo=
github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf/go.mod h1:1FsorU3vnXO9xS9SrhUp8fRb/6H/Zfll0rPt1i4GWaA=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 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/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.50.0 h1:H7fweIlBm0rXLs2q0XbalvJ6r0CUPFWK3/bB4N13e9M= github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0=
github.com/valyala/fasthttp v1.50.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ=
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= 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/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
@ -105,39 +142,46 @@ github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk= go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0=
go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo= go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -145,31 +189,53 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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/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.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.3/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.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 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-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= 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/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/tucnak/telebot.v2 v2.5.0 h1:i+NynLo443Vp+Zn3Gv9JBjh3Z/PaiKAQwcnhNI7y6Po=
gopkg.in/tucnak/telebot.v2 v2.5.0/go.mod h1:BgaIIx50PSRS9pG59JH+geT82cfvoJU/IaI5TJdN3v8=
gopkg.in/yaml.v2 v2.2.2/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-20200313102051-9f266ea9e77c/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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240202120244-c4ef330cfe5d h1:gbaDt35HMDqOK84WYmDIlXMI7rstUcRqNttaT6Kx1do= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240202120244-c4ef330cfe5d/go.mod h1:lTmpjry+8evVkXWbEC+WMOELcFkRD1lFMc7J09mOndM= penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240607202348-efe5f2bf3e8c h1:CWb4UcuNXhd1KTNOmy2U0TJO4+Qxgxrj5cwkyFqbgrk=
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240607202348-efe5f2bf3e8c/go.mod h1:+bPxq2wfW5S1gd+83vZYmHm33AE7nEBfznWS8AM1TKE=
penahub.gitlab.yandexcloud.net/devops/linters/golang.git v0.0.0-20240828181923-80f1728efccc h1:tKp1NYn+FJOq/mCyc4SJjcGdYdr1AhXnyw7f80uex0A=
penahub.gitlab.yandexcloud.net/devops/linters/golang.git v0.0.0-20240828181923-80f1728efccc/go.mod h1:i7M72RIpkSjcQtHID6KKj9RT/EYZ1rxS6tIPKWa/BSY=
penahub.gitlab.yandexcloud.net/external/trashlog.git v0.1.2-0.20240607135420-4279d2c37763 h1:fzNg+Cqt2sb5DabtjleFs8mILL+KP8/eBfl7EIP5kBQ=
penahub.gitlab.yandexcloud.net/external/trashlog.git v0.1.2-0.20240607135420-4279d2c37763/go.mod h1:3ml0dAGT8U8RhpevKBfRgG6yKZum8EI2uJxAb2WCIy4=
penahub.gitlab.yandexcloud.net/pena-services/customer v1.0.1-0.20240608222239-5c78187bf014 h1:ziG55nv824SGFZ02AfagKQC5D4ODirGXnpVPQTL6YFA=
penahub.gitlab.yandexcloud.net/pena-services/customer v1.0.1-0.20240608222239-5c78187bf014/go.mod h1:hIMkN5Xe01vAVaX22QWsGD87Oi93IfX1hJGqxy0oJbE=

@ -5,17 +5,28 @@ import (
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials" "github.com/minio/minio-go/v7/pkg/credentials"
"github.com/themakers/hlog"
"go.uber.org/zap" "go.uber.org/zap"
"go.uber.org/zap/zapcore" "go.uber.org/zap/zapcore"
mongo "penahub.gitlab.yandexcloud.net/backend/penahub_common/mongo" mongo "penahub.gitlab.yandexcloud.net/backend/penahub_common/mongo"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/client" "penahub.gitlab.yandexcloud.net/backend/verification/internal/client"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/config" "penahub.gitlab.yandexcloud.net/backend/verification/internal/config"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/initialize" "penahub.gitlab.yandexcloud.net/backend/verification/internal/initialize"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/models"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/server" "penahub.gitlab.yandexcloud.net/backend/verification/internal/server"
"penahub.gitlab.yandexcloud.net/external/trashlog.git/app"
"penahub.gitlab.yandexcloud.net/external/trashlog.git/wrappers/zaptrashlog"
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/customer_clients"
"time" "time"
) )
func Run(cfg *config.Config) { type Build struct {
Commit string
Version string
BuildTime int64
}
func Run(cfg *config.Config, build Build) {
cfgLogger := zap.NewDevelopmentConfig() cfgLogger := zap.NewDevelopmentConfig()
cfgLogger.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder cfgLogger.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
cfgLogger.EncoderConfig.ConsoleSeparator = " " cfgLogger.EncoderConfig.ConsoleSeparator = " "
@ -29,6 +40,19 @@ func Run(cfg *config.Config) {
ctx := context.Background() ctx := context.Background()
clickHouseLogger, err := zaptrashlog.NewCore(ctx, zap.InfoLevel, cfg.TrashLogHost, build.Version, build.Commit, build.BuildTime)
if err != nil {
panic(err)
}
loggerForHlog := logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
return zapcore.NewTee(core, clickHouseLogger)
}), zap.AddCallerSkip(2))
loggerHlog := hlog.New(loggerForHlog).Module(cfg.ModuleLogger)
loggerHlog.With(models.AllFields{})
loggerHlog.Emit(app.InfoSvcStarted{})
mongoDB, err := mongo.Connect(ctx, &mongo.ConnectDeps{ mongoDB, err := mongo.Connect(ctx, &mongo.ConnectDeps{
Configuration: &mongo.Configuration{ Configuration: &mongo.Configuration{
Host: cfg.MongoHost, Host: cfg.MongoHost,
@ -53,7 +77,7 @@ func Run(cfg *config.Config) {
logger.Fatal("MinioClient", zap.Error(err)) logger.Fatal("MinioClient", zap.Error(err))
} }
reps, err := initialize.NewRepositories(ctx, logger, mongoDB, minioClient) reps, err := initialize.NewRepositories(ctx, logger, mongoDB, minioClient, cfg.S3Folder, cfg.S3FileUrl)
if err != nil { if err != nil {
logger.Fatal("Repositories", zap.Error(err)) logger.Fatal("Repositories", zap.Error(err))
} }
@ -69,16 +93,34 @@ func Run(cfg *config.Config) {
ChatID: cfg.TelegramChannelID, ChatID: cfg.TelegramChannelID,
StagingURL: cfg.StagingURL, StagingURL: cfg.StagingURL,
}) })
cons := initialize.NewControllers(reps, telegram, client.NewCustomer(logger, cfg.CustomerSvcAddress)) cons := initialize.NewControllers(reps, telegram, customer_clients.NewCustomersClient(customer_clients.CustomersClientDeps{
Logger: logger,
CustomerServiceHost: cfg.CustomerRPCHost,
}))
httpSrv := server.NewHTTP(cfg, logger).Register(cons.List()...) userSrv := server.NewHTTP(server.ServerConfig{
Logger: logger,
Controllers: []server.Controller{cons.VerificationUser},
HLogger: loggerHlog,
})
adminSrv := server.NewHTTP(server.ServerConfig{
Logger: logger,
Controllers: []server.Controller{cons.VerificationAdmin},
HLogger: loggerHlog,
})
go func() { go func() {
err := httpSrv.Start() if err := userSrv.Start(cfg.HttpAddressUser); err != nil {
if err != nil { logger.Fatal("Server startup error", zap.Error(err))
logger.Fatal("CanNotServe", zap.Error(err))
} }
}() }()
gracefulShutdown(ctx, logger, httpSrv, mongoDB) go func() {
if err := adminSrv.Start(cfg.HttpAddressAdmin); err != nil {
logger.Fatal("Server startup error", zap.Error(err))
}
}()
gracefulShutdown(ctx, logger, []*server.Server{userSrv, adminSrv}, mongoDB)
} }

@ -10,7 +10,7 @@ import (
"syscall" "syscall"
) )
func gracefulShutdown(ctx context.Context, logger *zap.Logger, httpSrv *server.HTTP, mongoDB *mongo.Database) { func gracefulShutdown(ctx context.Context, logger *zap.Logger, httpSrvs []*server.Server, mongoDB *mongo.Database) {
interrupt := make(chan os.Signal, 1) interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM) signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)
killSignal := <-interrupt killSignal := <-interrupt
@ -21,9 +21,11 @@ func gracefulShutdown(ctx context.Context, logger *zap.Logger, httpSrv *server.H
logger.Info("AppTerminated") logger.Info("AppTerminated")
} }
if err := httpSrv.Stop(); err != nil { for _, srv := range httpSrvs {
if err := srv.Shutdown(ctx); err != nil {
logger.Error("HttpServerShutdown", zap.Error(err)) logger.Error("HttpServerShutdown", zap.Error(err))
} }
}
if err := mongoDB.Client().Disconnect(ctx); err != nil { if err := mongoDB.Client().Disconnect(ctx); err != nil {
logger.Error("MongoDB", zap.Error(err)) logger.Error("MongoDB", zap.Error(err))

@ -17,8 +17,9 @@ func NewCustomer(logger *zap.Logger, address string) *Customer {
return &Customer{logger: logger, address: address} return &Customer{logger: logger, address: address}
} }
func (c *Customer) UpdateAccountVerification(userId, status string) (*models.RespUpdateVerificationStatus, error) { func (c *Customer) UpdateAccountVerification(userId, status, token string) (*models.RespUpdateVerificationStatus, error) {
agent := fiber.Patch(fmt.Sprintf("%s/account/%s", c.address, userId)) agent := fiber.Patch(fmt.Sprintf("%s/account/%s", c.address, userId)).Set("Authorization", token)
fmt.Println("PATCHED", fmt.Sprintf("%s/account/%s", c.address, userId))
agent.JSON(&models.ReqCreateVerification{Status: status}) agent.JSON(&models.ReqCreateVerification{Status: status})
err := agent.Parse() err := agent.Parse()

@ -8,7 +8,8 @@ import (
type Config struct { type Config struct {
TelegramToken string `env:"TELEGRAM_TOKEN,required"` TelegramToken string `env:"TELEGRAM_TOKEN,required"`
TelegramChannelID int64 `env:"TELEGRAM_CHANNEL_ID,required"` TelegramChannelID int64 `env:"TELEGRAM_CHANNEL_ID,required"`
HttpAddress string `env:"HTTP_ADDRESS,required"` HttpAddressUser string `env:"HTTP_ADDRESS_USER,required"`
HttpAddressAdmin string `env:"HTTP_ADDRESS_ADMIN,required"`
MongoHost string `env:"MONGO_HOST,required"` MongoHost string `env:"MONGO_HOST,required"`
MongoPort string `env:"MONGO_PORT,required"` MongoPort string `env:"MONGO_PORT,required"`
MongoUser string `env:"MONGO_USER,required"` MongoUser string `env:"MONGO_USER,required"`
@ -20,6 +21,11 @@ type Config struct {
S3SecretKey string `env:"S3_SECRET_KEY,required"` S3SecretKey string `env:"S3_SECRET_KEY,required"`
CustomerSvcAddress string `env:"CUSTOMER_SVC_ADDRESS,required"` CustomerSvcAddress string `env:"CUSTOMER_SVC_ADDRESS,required"`
StagingURL string `env:"STAGING_URL,required"` StagingURL string `env:"STAGING_URL,required"`
S3Folder string `env:"S3_FOLDER,required"`
S3FileUrl string `env:"S3_FILE_URL,required"`
CustomerRPCHost string `env:"CUSTOMER_RPC_HOST,required"`
TrashLogHost string `env:"TRASH_LOG_HOST,required"`
ModuleLogger string `env:"MODULE_LOGGER,required"`
} }
func NewConfig(file ...string) (*Config, error) { func NewConfig(file ...string) (*Config, error) {

@ -0,0 +1,12 @@
package admin
import "github.com/gofiber/fiber/v2"
func (r *VerifyAdminController) Register(router fiber.Router) {
router.Get("/verification/:userID", r.GetVerification)
router.Patch("/verification", r.SetVerificationStatus)
}
func (r *VerifyAdminController) Name() string {
return ""
}

@ -0,0 +1,93 @@
package admin
import (
"github.com/gofiber/fiber/v2"
"penahub.gitlab.yandexcloud.net/backend/penahub_common/log_mw"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/models"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/repository"
"penahub.gitlab.yandexcloud.net/backend/verification/pkg/validate_controllers"
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/customer_clients"
)
type VerifyAdminControllerDeps struct {
Repository *repository.VerificationRepository
Customer *customer_clients.CustomersClient
}
type VerifyAdminController struct {
repository *repository.VerificationRepository
customer *customer_clients.CustomersClient
}
func NewVerificationAdminController(deps VerifyAdminControllerDeps) *VerifyAdminController {
return &VerifyAdminController{
repository: deps.Repository,
customer: deps.Customer,
}
}
func (r *VerifyAdminController) SetVerificationStatus(c *fiber.Ctx) error {
var req models.ReqSetVerification
hloger := log_mw.ExtractLogger(c)
err := c.BodyParser(&req)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
errValidate := validate_controllers.ValidateStruct(&req)
if errValidate != nil {
return c.Status(fiber.StatusBadRequest).JSON(errValidate)
}
updated, err := r.repository.Update(c.Context(), &models.Verification{
ID: req.ID,
Accepted: req.Accepted,
Status: req.Status,
Comment: req.Comment,
TaxNumber: req.TaxNumber,
})
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
}
if req.Accepted {
_, err := r.customer.SetVerifyAccount(c.Context(), updated.UserID, req.Status)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
}
hloger.Emit(models.InfoVerificationAccepted{
CtxID: updated.ID,
KeyStatus: updated.Status,
CtxTaxNumber: updated.TaxNumber,
})
}
if !req.Accepted {
hloger.Emit(models.InfoVerificationDeclined{
CtxID: updated.ID,
KeyStatus: updated.Status,
CtxComment: updated.Comment,
})
}
return c.SendStatus(fiber.StatusOK)
}
func (r *VerifyAdminController) GetVerification(c *fiber.Ctx) error {
userID := c.Params("userID")
if userID == "" {
return fiber.NewError(fiber.StatusUnauthorized)
}
resp, err := r.repository.GetByUserID(c.Context(), userID)
if err != nil {
return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
}
if resp == nil {
return c.SendStatus(fiber.StatusNotFound)
}
return c.Status(fiber.StatusOK).JSON(resp)
}

@ -0,0 +1,13 @@
package user
import "github.com/gofiber/fiber/v2"
func (r *VerifyUserController) Register(router fiber.Router) {
router.Get("/verification", r.GetVerification)
router.Post("/verification", r.CreateVerification)
router.Put("/verification", r.SetVerificationFile)
}
func (r *VerifyUserController) Name() string {
return ""
}

@ -1,44 +1,39 @@
package controllers package user
import ( import (
"errors" "errors"
"mime/multipart"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
"mime/multipart"
"penahub.gitlab.yandexcloud.net/backend/penahub_common/log_mw"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/client" "penahub.gitlab.yandexcloud.net/backend/verification/internal/client"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/models" "penahub.gitlab.yandexcloud.net/backend/verification/internal/models"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/repository" "penahub.gitlab.yandexcloud.net/backend/verification/internal/repository"
"penahub.gitlab.yandexcloud.net/backend/verification/pkg/validate_controllers"
) )
type VerificationController struct { type VerifyUserControllerDeps struct {
Repository *repository.VerificationRepository
Telegram *client.Telegram
}
type VerifyUserController struct {
repository *repository.VerificationRepository repository *repository.VerificationRepository
telegram *client.Telegram telegram *client.Telegram
customer *client.Customer
} }
func NewVerificationController(rep *repository.VerificationRepository, telegram *client.Telegram, customer *client.Customer) *VerificationController { func NewVerificationUserController(deps VerifyUserControllerDeps) *VerifyUserController {
return &VerificationController{repository: rep, telegram: telegram, customer: customer} return &VerifyUserController{
} repository: deps.Repository,
telegram: deps.Telegram,
func (r *VerificationController) GetRoutes() []Route {
return []Route{
{"GET", "/verification/:userID", "GetVerification", r.GetVerification},
{"POST", "/verification", "CreateVerification", r.CreateVerification},
{"PATCH", "/verification", "SetVerificationStatus", r.SetVerificationStatus},
{"PATCH", "/verification/file", "SetVerificationFile", r.SetVerificationFile},
} }
} }
func (r *VerificationController) GetVerification(c *fiber.Ctx) error { func (r *VerifyUserController) GetVerification(c *fiber.Ctx) error {
userID := c.Params("userID") userID := c.Locals(models.UserCtxKey).(string)
if userID == "" {
userID = c.Locals("userID").(string)
if userID == "" { if userID == "" {
return fiber.NewError(fiber.StatusUnauthorized) return fiber.NewError(fiber.StatusUnauthorized)
} }
}
resp, err := r.repository.GetByUserID(c.Context(), userID) resp, err := r.repository.GetByUserID(c.Context(), userID)
if err != nil { if err != nil {
@ -52,25 +47,22 @@ func (r *VerificationController) GetVerification(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON(resp) return c.Status(fiber.StatusOK).JSON(resp)
} }
func (r *VerificationController) CreateVerification(c *fiber.Ctx) error { func (r *VerifyUserController) CreateVerification(c *fiber.Ctx) error {
var req models.ReqCreateVerification var req models.ReqCreateVerification
userID := c.Params("userID")
baseURL := c.BaseURL() baseURL := c.BaseURL()
hloger := log_mw.ExtractLogger(c)
if userID == "" { userID := c.Locals(models.UserCtxKey).(string)
userID = c.Locals("userID").(string)
if userID == "" { if userID == "" {
return fiber.NewError(fiber.StatusUnauthorized) return fiber.NewError(fiber.StatusUnauthorized)
} }
}
err := c.BodyParser(&req) err := c.BodyParser(&req)
if err != nil { if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error()) return fiber.NewError(fiber.StatusBadRequest, err.Error())
} }
errValidate := validateStruct(&req) errValidate := validate_controllers.ValidateStruct(&req)
if errValidate != nil { if errValidate != nil {
return c.Status(fiber.StatusBadRequest).JSON(errValidate) return c.Status(fiber.StatusBadRequest).JSON(errValidate)
} }
@ -89,13 +81,6 @@ func (r *VerificationController) CreateVerification(c *fiber.Ctx) error {
return fiber.NewError(fiber.StatusBadRequest, "rule file required") return fiber.NewError(fiber.StatusBadRequest, "rule file required")
} }
// EGRULE FILE
egruleFH, err := c.FormFile("egrule")
if err != nil || egruleFH.Size == 0 || egruleFH == nil {
return fiber.NewError(fiber.StatusBadRequest, "egrule file required")
}
// CERTIFICATE FILE // CERTIFICATE FILE
var certFH *multipart.FileHeader var certFH *multipart.FileHeader
if req.Status == "nko" { if req.Status == "nko" {
@ -112,7 +97,7 @@ func (r *VerificationController) CreateVerification(c *fiber.Ctx) error {
Accepted: false, Accepted: false,
Status: req.Status, Status: req.Status,
Comment: "", Comment: "",
}, innFH, ruleFH, egruleFH, certFH) }, innFH, ruleFH, certFH)
if err != nil { if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error()) return fiber.NewError(fiber.StatusInternalServerError, err.Error())
} }
@ -122,55 +107,24 @@ func (r *VerificationController) CreateVerification(c *fiber.Ctx) error {
return fiber.NewError(fiber.StatusInternalServerError, err.Error()) return fiber.NewError(fiber.StatusInternalServerError, err.Error())
} }
hloger.Emit(models.InfoVerificationRequested{
CtxID: result.ID,
KeyStatus: result.Status,
})
return c.Status(fiber.StatusOK).JSON(result) return c.Status(fiber.StatusOK).JSON(result)
} }
func (r *VerificationController) SetVerificationStatus(c *fiber.Ctx) error { func (r *VerifyUserController) SetVerificationFile(c *fiber.Ctx) error {
var req models.ReqSetVerification
err := c.BodyParser(&req)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
errValidate := validateStruct(&req)
if errValidate != nil {
return c.Status(fiber.StatusBadRequest).JSON(errValidate)
}
_, err = r.repository.Update(c.Context(), &models.Verification{
ID: req.ID,
Accepted: req.Accepted,
Status: req.Status,
Comment: req.Comment,
TaxNumber: req.TaxNumber,
})
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
}
if req.Accepted {
_, err := r.customer.UpdateAccountVerification(req.ID, req.Status)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
}
}
return c.SendStatus(fiber.StatusOK)
}
func (r *VerificationController) SetVerificationFile(c *fiber.Ctx) error {
userID := c.Params("userID")
baseURL := c.BaseURL() baseURL := c.BaseURL()
hloger := log_mw.ExtractLogger(c)
if userID == "" { userID := c.Locals(models.UserCtxKey).(string)
userID = c.Locals("userID").(string)
if userID == "" { if userID == "" {
return fiber.NewError(fiber.StatusUnauthorized) return fiber.NewError(fiber.StatusUnauthorized)
} }
}
availableFiles := []string{"inn", "rule", "egrule", "certificate"} availableFiles := []string{"inn", "rule", "certificate"}
var err error var err error
var fileHeader *multipart.FileHeader var fileHeader *multipart.FileHeader
var result *models.Verification var result *models.Verification
@ -197,5 +151,10 @@ func (r *VerificationController) SetVerificationFile(c *fiber.Ctx) error {
return fiber.NewError(fiber.StatusInternalServerError, err.Error()) return fiber.NewError(fiber.StatusInternalServerError, err.Error())
} }
hloger.Emit(models.InfoVerificationRequested{
CtxID: result.ID,
KeyStatus: result.Status,
})
return c.SendStatus(fiber.StatusOK) return c.SendStatus(fiber.StatusOK)
} }

@ -1,11 +1,11 @@
package controllers package user
import ( import (
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
) )
type VerificationTestSuite struct { type VerificationTestSuite struct {
controller *VerificationController controller *VerifyUserController
suite.Suite suite.Suite
} }

@ -2,33 +2,25 @@ package initialize
import ( import (
"penahub.gitlab.yandexcloud.net/backend/verification/internal/client" "penahub.gitlab.yandexcloud.net/backend/verification/internal/client"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/controllers" "penahub.gitlab.yandexcloud.net/backend/verification/internal/controllers/admin"
"reflect" "penahub.gitlab.yandexcloud.net/backend/verification/internal/controllers/user"
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/customer_clients"
) )
type Controller interface {
GetRoutes() []controllers.Route
}
type Controllers struct { type Controllers struct {
Verification *controllers.VerificationController VerificationAdmin *admin.VerifyAdminController
VerificationUser *user.VerifyUserController
} }
func (c *Controllers) List() []Controller { func NewControllers(reps *Repositories, telegram *client.Telegram, customer *customer_clients.CustomersClient) *Controllers {
fields := reflect.ValueOf(c).Elem() return &Controllers{
VerificationAdmin: admin.NewVerificationAdminController(admin.VerifyAdminControllerDeps{
var controllersArr []Controller Repository: reps.Verification,
for i := 0; i < fields.NumField(); i++ { Customer: customer,
vf := fields.Field(i) }),
VerificationUser: user.NewVerificationUserController(user.VerifyUserControllerDeps{
if vf.Type().Implements(reflect.TypeOf((*Controller)(nil)).Elem()) { Repository: reps.Verification,
controllersArr = append(controllersArr, vf.Interface().(Controller)) Telegram: telegram,
}),
} }
} }
return controllersArr
}
func NewControllers(reps *Repositories, telegram *client.Telegram, customer *client.Customer) *Controllers {
return &Controllers{Verification: controllers.NewVerificationController(reps.Verification, telegram, customer)}
}

@ -16,13 +16,8 @@ func NewRepositories(
ctx context.Context, ctx context.Context,
logger *zap.Logger, logger *zap.Logger,
mongoDB *mongo.Database, mongoDB *mongo.Database,
s3 *minio.Client) (*Repositories, error) { s3 *minio.Client, folder, url string) (*Repositories, error) {
reps := &Repositories{Verification: repository.NewVerificationRepository(logger, mongoDB, s3)} reps := &Repositories{Verification: repository.NewVerificationRepository(logger, mongoDB, s3, folder, url)}
err := reps.Verification.Init(ctx)
if err != nil {
return nil, err
}
return reps, nil return reps, nil
} }

@ -0,0 +1,27 @@
package models
type AllFields struct {
CtxID string
KeyStatus string
CtxComment string
CtxTaxNumber string
CtxUserIP string
CtxUserPort string
KeyDomain string
KeyPath string
}
type InfoVerificationRequested struct { //эмиттить при подаче на верификацию и при замене файла
CtxID string // - айдишник верификации
KeyStatus string // статус, который пользователь хочет обрести после верификации
}
type InfoVerificationDeclined struct {
CtxID string // - айдишник верификации
KeyStatus string // статус, который пользователь хочет обрести после верификации
CtxComment string // комментарий при отклонении
}
type InfoVerificationAccepted struct {
CtxID string // - айдишник верификации
KeyStatus string // статус, который пользователь хочет обрести после верификации
CtxTaxNumber string
}

@ -5,3 +5,6 @@ type RespErrorValidate struct {
Tag string `json:"tag"` Tag string `json:"tag"`
Value string `json:"value"` Value string `json:"value"`
} }
const UserCtxKey = "userID"
const TokenCtxKey = "token"

@ -2,14 +2,11 @@ package repository
import ( import (
"context" "context"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/minio/minio-go/v7/pkg/policy"
"github.com/minio/minio-go/v7/pkg/set"
"mime/multipart" "mime/multipart"
"strings"
"time" "time"
"strings"
"github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson"
@ -24,93 +21,29 @@ type VerificationRepository struct {
logger *zap.Logger logger *zap.Logger
mongo *mongo.Collection mongo *mongo.Collection
s3 *minio.Client s3 *minio.Client
folder, url string
} }
const ( const (
VerificationEndpointURL = "https://hub.pena.digital" VerificationEndpointURL = "https://s3.timeweb.cloud"
VerificationBucket = "verification1" VerificationBucket = "3c580be9-cf31f296-d055-49cf-b39e-30c7959dc17b"
VerificationCollection = "verification" VerificationCollection = "verification"
) )
func NewVerificationRepository(logger *zap.Logger, mongoDb *mongo.Database, s3 *minio.Client) *VerificationRepository { func NewVerificationRepository(logger *zap.Logger, mongoDb *mongo.Database, s3 *minio.Client, folder, url string) *VerificationRepository {
return &VerificationRepository{ return &VerificationRepository{
logger: logger, logger: logger,
mongo: mongoDb.Collection(VerificationCollection), mongo: mongoDb.Collection(VerificationCollection),
s3: s3, s3: s3,
folder: folder,
url: url,
} }
} }
func (r *VerificationRepository) Init(ctx context.Context) error {
ok, err := r.s3.BucketExists(ctx, VerificationBucket)
if r.err(err) {
return err
}
if !ok {
err = r.s3.MakeBucket(ctx, VerificationBucket, minio.MakeBucketOptions{ObjectLocking: false})
if r.err(err) {
return err
}
policyConsoleStatement := policy.Statement{
Actions: set.CreateStringSet("*"),
Conditions: policy.ConditionMap{
"StringLike": policy.ConditionKeyMap{
"aws:referer": set.CreateStringSet(fmt.Sprintf("https://console.cloud.yandex.*/folders/*/storage/buckets/%s*", VerificationBucket)),
},
},
Effect: "Allow",
Principal: policy.User{AWS: set.CreateStringSet("*")},
Resources: set.CreateStringSet(fmt.Sprintf("arn:aws:s3:::%s/*", VerificationBucket),
fmt.Sprintf("arn:aws:s3:::%s", VerificationBucket)),
Sid: "console-statement",
}
policyServiceAccount := policy.Statement{
Actions: set.CreateStringSet("*"),
Conditions: nil,
Effect: "Allow",
Principal: policy.User{CanonicalUser: set.CreateStringSet("ajelmc4tjbct675tjdh9")},
Resources: set.CreateStringSet(fmt.Sprintf("arn:aws:s3:::%s/*", VerificationBucket),
fmt.Sprintf("arn:aws:s3:::%s", VerificationBucket)),
Sid: "service-account-statement",
}
policySharingBucket := policy.Statement{
Actions: set.CreateStringSet("s3:GetObject"),
Conditions: nil,
Effect: "Allow",
Principal: policy.User{AWS: set.CreateStringSet("*")},
Resources: set.CreateStringSet(fmt.Sprintf("arn:aws:s3:::%s/*", VerificationBucket),
fmt.Sprintf("arn:aws:s3:::%s", VerificationBucket)),
Sid: "sharing-bucket",
}
p := policy.BucketAccessPolicy{Version: "2012-10-17", Statements: []policy.Statement{
policyConsoleStatement,
policyServiceAccount,
policySharingBucket,
}}
outPolicy, err := json.Marshal(&p)
if r.err(err) {
return err
}
err = r.s3.SetBucketPolicy(ctx, VerificationBucket, string(outPolicy))
if r.err(err) {
return err
}
}
return nil
}
func (r *VerificationRepository) Insert( func (r *VerificationRepository) Insert(
ctx context.Context, ctx context.Context,
userID string, userID string,
record *models.Verification, record *models.Verification,
innFH, ruleFH, egruleFH, certFH *multipart.FileHeader) (*models.Verification, error) { innFH, ruleFH, certFH *multipart.FileHeader) (*models.Verification, error) {
now := time.Now() now := time.Now()
record.ID = primitive.NewObjectIDFromTimestamp(now).Hex() record.ID = primitive.NewObjectIDFromTimestamp(now).Hex()
record.UpdatedAt = now record.UpdatedAt = now
@ -121,7 +54,7 @@ func (r *VerificationRepository) Insert(
return nil, err return nil, err
} }
_, err = r.s3.PutObject(ctx, VerificationBucket, fmt.Sprintf("%s/%s", userID, innFH.Filename), inn, innFH.Size, minio.PutObjectOptions{}) _, err = r.s3.PutObject(ctx, VerificationBucket, fmt.Sprintf("%s/%s/%s", r.folder, userID, innFH.Filename), inn, innFH.Size, minio.PutObjectOptions{})
if r.err(err) { if r.err(err) {
return nil, err return nil, err
} }
@ -132,18 +65,7 @@ func (r *VerificationRepository) Insert(
} }
// Put rule file // Put rule file
_, err = r.s3.PutObject(ctx, VerificationBucket, fmt.Sprintf("%s/%s", userID, ruleFH.Filename), rule, ruleFH.Size, minio.PutObjectOptions{}) _, err = r.s3.PutObject(ctx, VerificationBucket, fmt.Sprintf("%s/%s/%s", r.folder, userID, ruleFH.Filename), rule, ruleFH.Size, minio.PutObjectOptions{})
if r.err(err) {
return nil, err
}
// Put egrule file
egrule, err := egruleFH.Open()
if r.err(err) {
return nil, err
}
_, err = r.s3.PutObject(ctx, VerificationBucket, fmt.Sprintf("%s/%s", userID, egruleFH.Filename), egrule, egruleFH.Size, minio.PutObjectOptions{})
if r.err(err) { if r.err(err) {
return nil, err return nil, err
} }
@ -155,7 +77,7 @@ func (r *VerificationRepository) Insert(
return nil, err return nil, err
} }
_, err = r.s3.PutObject(ctx, VerificationBucket, fmt.Sprintf("%s/%s", userID, certFH.Filename), cert, certFH.Size, minio.PutObjectOptions{}) _, err = r.s3.PutObject(ctx, VerificationBucket, fmt.Sprintf("%s/%s/%s", r.folder, userID, certFH.Filename), cert, certFH.Size, minio.PutObjectOptions{})
if r.err(err) { if r.err(err) {
return nil, err return nil, err
} }
@ -163,7 +85,7 @@ func (r *VerificationRepository) Insert(
record.Files = []models.VerificationFile{ record.Files = []models.VerificationFile{
{ {
Name: "certificate", Name: "certificate",
Url: fmt.Sprintf("%s/%s/%s/%s", VerificationEndpointURL, VerificationBucket, userID, certFH.Filename), Url: fmt.Sprintf("%s/%s/%s/%s", r.url, r.folder, userID, certFH.Filename),
}, },
} }
} }
@ -172,15 +94,11 @@ func (r *VerificationRepository) Insert(
record.Files = append(record.Files, []models.VerificationFile{ record.Files = append(record.Files, []models.VerificationFile{
{ {
Name: "inn", Name: "inn",
Url: fmt.Sprintf("%s/%s/%s/%s", VerificationEndpointURL, VerificationBucket, userID, innFH.Filename), Url: fmt.Sprintf("%s/%s/%s/%s", r.url, r.folder, userID, innFH.Filename),
}, },
{ {
Name: "rule", Name: "rule",
Url: fmt.Sprintf("%s/%s/%s/%s", VerificationEndpointURL, VerificationBucket, userID, ruleFH.Filename), Url: fmt.Sprintf("%s/%s/%s/%s", r.url, r.folder, userID, ruleFH.Filename),
},
{
Name: "egrule",
Url: fmt.Sprintf("%s/%s/%s/%s", VerificationEndpointURL, VerificationBucket, userID, egruleFH.Filename),
}, },
}...) }...)
@ -272,12 +190,12 @@ func (r *VerificationRepository) UpdateFile(ctx context.Context, userID, fileNam
return nil, err return nil, err
} }
_, err = r.s3.PutObject(ctx, VerificationBucket, fmt.Sprintf("%s/%s", userID, fileHeader.Filename), fileReader, fileHeader.Size, minio.PutObjectOptions{}) _, err = r.s3.PutObject(ctx, VerificationBucket, fmt.Sprintf("%s/%s/%s", r.folder, userID, fileHeader.Filename), fileReader, fileHeader.Size, minio.PutObjectOptions{})
if r.err(err) { if r.err(err) {
return nil, err return nil, err
} }
fileURL := fmt.Sprintf("%s/%s/%s/%s", VerificationEndpointURL, VerificationBucket, userID, fileHeader.Filename) fileURL := fmt.Sprintf("%s/%s/%s/%s", r.url, r.folder, userID, fileHeader.Filename)
// remove old file // remove old file
verification, err := r.GetByUserID(ctx, userID) verification, err := r.GetByUserID(ctx, userID)
@ -289,14 +207,13 @@ func (r *VerificationRepository) UpdateFile(ctx context.Context, userID, fileNam
return nil, fmt.Errorf("no verification found") return nil, fmt.Errorf("no verification found")
} }
fmt.Println("BUG",verification.Files)
found := false found := false
for iterator, file := range verification.Files { for iterator, file := range verification.Files {
if file.Name != fileName { if file.Name != fileName {
continue continue
} }
objectName := strings.ReplaceAll(file.Url, fmt.Sprintf("%v/%v/", VerificationEndpointURL, VerificationBucket), "") objectName := strings.ReplaceAll(file.Url, r.url, "")
if err = r.s3.RemoveObject(ctx, VerificationBucket, objectName, minio.RemoveObjectOptions{}); r.err(err) { if err = r.s3.RemoveObject(ctx, VerificationBucket, objectName, minio.RemoveObjectOptions{}); r.err(err) {
return nil, err return nil, err
} }
@ -310,6 +227,8 @@ func (r *VerificationRepository) UpdateFile(ctx context.Context, userID, fileNam
} }
// update in mongodb // update in mongodb
result, err := r.Update(ctx, &models.Verification{ID: verification.ID, Files: verification.Files}) result, err := r.Update(ctx, &models.Verification{ID: verification.ID, Files: verification.Files})
if r.err(err) { if r.err(err) {
return nil, err return nil, err

@ -1,21 +1,29 @@
package server package server
import ( import (
"context"
"fmt"
"github.com/gofiber/contrib/fiberzap" "github.com/gofiber/contrib/fiberzap"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/recover" "github.com/gofiber/fiber/v2/middleware/recover"
"github.com/themakers/hlog"
"go.uber.org/zap" "go.uber.org/zap"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/config" "penahub.gitlab.yandexcloud.net/backend/penahub_common/log_mw"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/initialize"
) )
type HTTP struct { type ServerConfig struct {
fiber *fiber.App Logger *zap.Logger
cfg *config.Config Controllers []Controller
logger *zap.Logger HLogger hlog.Logger
} }
func NewHTTP(cfg *config.Config, logger *zap.Logger) *HTTP { type Server struct {
Logger *zap.Logger
Controllers []Controller
app *fiber.App
}
func NewHTTP(cfg ServerConfig) *Server {
srv := fiber.New(fiber.Config{ srv := fiber.New(fiber.Config{
AppName: "Verification", AppName: "Verification",
ErrorHandler: fiber.DefaultErrorHandler, ErrorHandler: fiber.DefaultErrorHandler,
@ -24,30 +32,52 @@ func NewHTTP(cfg *config.Config, logger *zap.Logger) *HTTP {
srv.Use( srv.Use(
recover.New(recover.Config{EnableStackTrace: true}), recover.New(recover.Config{EnableStackTrace: true}),
fiberzap.New(fiberzap.Config{Logger: logger}), fiberzap.New(fiberzap.Config{Logger: cfg.Logger}),
LocalJwt(), LocalJwt(),
Jwt(), Jwt(),
log_mw.ContextLogger(cfg.HLogger),
) )
return &HTTP{fiber: srv, cfg: cfg, logger: logger} s := &Server{
Logger: cfg.Logger,
Controllers: cfg.Controllers,
app: srv,
} }
// Register - автоматически регистрирует все контроллеры. s.registerRoutes()
func (srv *HTTP) Register(controllers ...initialize.Controller) *HTTP {
for _, controller := range controllers { return s
for _, route := range controller.GetRoutes() {
srv.fiber.Add(route.Method, route.Path, route.Handler).Name(route.Name)
}
}
return srv
} }
// Start - запускает http сервер. func (s *Server) Start(addr string) error {
func (srv *HTTP) Start() error { if err := s.app.Listen(addr); err != nil {
return srv.fiber.Listen(srv.cfg.HttpAddress) s.Logger.Error("Failed to start server", zap.Error(err))
return err
}
return nil
} }
// Stop - останавливает http сервер. func (s *Server) Shutdown(ctx context.Context) error {
func (srv *HTTP) Stop() error { return s.app.Shutdown()
return srv.fiber.Shutdown() }
func (s *Server) registerRoutes() {
for _, c := range s.Controllers {
router := s.app.Group(c.Name())
c.Register(router)
}
}
type Controller interface {
Register(router fiber.Router)
Name() string
}
func (s *Server) ListRoutes() {
fmt.Println("Registered routes:")
for _, stack := range s.app.Stack() {
for _, route := range stack {
fmt.Printf("%s %s\n", route.Method, route.Path)
}
}
} }

@ -1,6 +1,7 @@
package server package server
import ( import (
"penahub.gitlab.yandexcloud.net/backend/verification/internal/models"
"strings" "strings"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
@ -20,7 +21,7 @@ func LocalJwt() fiber.Handler {
func Jwt() fiber.Handler { func Jwt() fiber.Handler {
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
// check LocalJwt // check LocalJwt
if c.Locals("userID") != nil { if c.Locals(models.UserCtxKey) != nil {
return c.Next() return c.Next()
} }
@ -38,7 +39,8 @@ func Jwt() fiber.Handler {
return fiber.NewError(fiber.StatusUnauthorized, "empty user") return fiber.NewError(fiber.StatusUnauthorized, "empty user")
} }
c.Locals("userID", jwt.GetUserID()) c.Locals(models.UserCtxKey, jwt.GetUserID())
c.Locals(models.TokenCtxKey, c.Get(jwt_adapter.DefaultHeaderKey))
return c.Next() return c.Next()
} }
} }

@ -61,10 +61,6 @@ paths:
type: file type: file
contentMediaType: application/pdf contentMediaType: application/pdf
contentEncoding: base64 contentEncoding: base64
egrule:
type: file
contentMediaType: application/pdf
contentEncoding: base64
certificate: certificate:
type: file type: file
description: только для status == nko description: только для status == nko

@ -1,4 +1,4 @@
package controllers package validate_controllers
import ( import (
"reflect" "reflect"
@ -18,7 +18,7 @@ type Route struct {
} }
// validateStruct - возвращает строку с ошибкой, если структура не прошла валидацию. // validateStruct - возвращает строку с ошибкой, если структура не прошла валидацию.
func validateStruct(s any) []*models.RespErrorValidate { func ValidateStruct(s any) []*models.RespErrorValidate {
err := validate.Struct(s) err := validate.Struct(s)
var errorsValidate []*models.RespErrorValidate var errorsValidate []*models.RespErrorValidate

@ -1,4 +1,3 @@
MONGO_DATABASE_NAME=verification MONGO_DATABASE_NAME=verification
HTTP_ADDRESS=:7035 HTTP_ADDRESS=:7035
CUSTOMER_SVC_ADDRESS=https://admin.pena.digital/customer CUSTOMER_SVC_ADDRESS=http://10.8.0.8:8065
STAGING_URL=https://sadmin.pena

20
test.env Normal file

@ -0,0 +1,20 @@
TELEGRAM_TOKEN=6712573453:AAFbioUuXf0Te73MUCqa0_h09qEQ1iQREas
TELEGRAM_CHANNEL_ID=542073142
HTTP_ADDRESS_USER=0.0.0.0:8080
HTTP_ADDRESS_ADMIN=0.0.0.0:8081
MONGO_HOST=localhost
MONGO_PORT=27020
MONGO_USER=test
MONGO_PASSWORD=test
MONGO_AUTH=admin
MONGO_DATABASE_NAME=admin
S3_ENDPOINT=localhost:9005
S3_ACCESS_KEY_ID=admin
S3_SECRET_KEY=admin123
CUSTOMER_SVC_ADDRESS=localhost:9003
STAGING_URL=https://sadmin.pena
S3_FOLDER=videodata
S3_FILE_URL=http://localhost:9005/videodata
CUSTOMER_RPC_HOST=localhost:9003
TRASH_LOG_HOST=localhost:7113
MODULE_LOGGER=verify-local

@ -0,0 +1,60 @@
package e2e
import (
"bytes"
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/stretchr/testify/assert"
"io"
"mime/multipart"
"os"
"penahub.gitlab.yandexcloud.net/backend/verification/tests/helpers"
"testing"
)
func Test_SetVerify(t *testing.T) {
url := "http://localhost:8080/verification"
client := fiber.AcquireClient()
token, err := helpers.CreateJwt("64e53ed187392e122e5d3d50")
assert.NoError(t, err)
fmt.Println(token)
assert.NoError(t, err)
var requestBody bytes.Buffer
writer := multipart.NewWriter(&requestBody)
err = writer.WriteField("status", "nko")
assert.NoError(t, err)
files := []struct {
fieldName string
filePath string
}{
{"inn", "files/inn"},
{"rule", "files/rule"},
{"certificate", "files/certificate"},
}
for _, file := range files {
fileWriter, err := writer.CreateFormFile(file.fieldName, file.filePath)
assert.NoError(t, err)
f, err := os.Open(file.filePath)
assert.NoError(t, err)
defer f.Close()
_, err = io.Copy(fileWriter, f)
assert.NoError(t, err)
}
writer.Close()
agent := client.Post(url).Body(requestBody.Bytes()).ContentType(writer.FormDataContentType())
agent.Set("Authorization", fmt.Sprintf("Bearer %s", token))
statusCode, respBody, errs := agent.Bytes()
if len(errs) > 0 {
assert.NoError(t, errs[0])
}
assert.Equal(t, 200, statusCode)
fmt.Println(string(respBody))
}

@ -0,0 +1 @@
аываывавыфавыавыфаываываываывпыпыфывиываолиыврмиыврмиывимролыиф

1
tests/e2e/files/egrule Normal file

@ -0,0 +1 @@
аываывавыфавыавыфаываываываывпыпыфывиываолиыврмиыврмиывимролыиф

1
tests/e2e/files/inn Normal file

@ -0,0 +1 @@
аываывавыфавыавыфаываываываывпыпыфывиываолиыврмиыврмиывимролыиф

1
tests/e2e/files/rule Normal file

@ -0,0 +1 @@
аываывавыфавыавыфаываываываывпыпыфывиываолиыврмиыврмиывимролыиф

@ -0,0 +1,57 @@
package e2e
import (
"encoding/json"
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/stretchr/testify/assert"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/models"
"penahub.gitlab.yandexcloud.net/backend/verification/tests/helpers"
"testing"
)
func Test_GetVerifyAdmin(t *testing.T) {
url := "http://localhost:8081/verification/64e53ed187392e122e5d3d50"
client := fiber.AcquireClient()
token, err := helpers.CreateJwt("64e53ed187392e122e5d3d51")
assert.NoError(t, err)
agent := client.Get(url)
agent.Set("Authorization", fmt.Sprintf("Bearer %s", token))
statusCode, respBody, errs := agent.Bytes()
if len(errs) > 0 {
assert.NoError(t, errs[0])
}
assert.Equal(t, 200, statusCode)
var resp models.Verification
err = json.Unmarshal(respBody, &resp)
assert.NoError(t, err)
fmt.Println(resp)
url = "http://localhost:8081/verification"
client2 := fiber.AcquireClient()
req := models.ReqSetVerification{
ID: resp.ID,
Status: "nko",
Comment: "MOLODEC, GOOD JOB",
Accepted: true,
TaxNumber: "000-000-000",
}
reqBody, err := json.Marshal(req)
assert.NoError(t, err)
agent2 := client2.Patch(url).Body(reqBody).ContentType("application/json")
agent2.Set("Authorization", fmt.Sprintf("Bearer %s", token))
statusCode, _, errs = agent2.Bytes()
if len(errs) > 0 {
fmt.Println(errs[0])
assert.NoError(t, errs[0])
}
assert.Equal(t, 200, statusCode)
}

@ -0,0 +1,33 @@
package e2e
import (
"encoding/json"
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/stretchr/testify/assert"
"penahub.gitlab.yandexcloud.net/backend/verification/internal/models"
"penahub.gitlab.yandexcloud.net/backend/verification/tests/helpers"
"testing"
)
func Test_Get_Verify_User(t *testing.T) {
url := "http://localhost:8080/verification"
client := fiber.AcquireClient()
token, err := helpers.CreateJwt("64e53ed187392e122e5d3d50")
assert.NoError(t, err)
agent := client.Get(url)
agent.Set("Authorization", fmt.Sprintf("Bearer %s", token))
statusCode, respBody, errs := agent.Bytes()
if len(errs) > 0 {
assert.NoError(t, errs[0])
}
assert.Equal(t, 200, statusCode)
var resp models.Verification
err = json.Unmarshal(respBody, &resp)
assert.NoError(t, err)
fmt.Println(resp)
}

@ -0,0 +1,59 @@
package e2e
import (
"bytes"
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/stretchr/testify/assert"
"io"
"mime/multipart"
"os"
"penahub.gitlab.yandexcloud.net/backend/verification/tests/helpers"
"testing"
)
func Test_PutFile(t *testing.T) {
url := "http://localhost:8080/verification"
client := fiber.AcquireClient()
token, err := helpers.CreateJwt("64e53ed187392e122e5d3d51")
assert.NoError(t, err)
fmt.Println(token)
assert.NoError(t, err)
var requestBody bytes.Buffer
writer := multipart.NewWriter(&requestBody)
files := []struct {
fieldName string
filePath string
}{
{"inn", "files/inn"},
{"rule", "files/rule"},
{"certificate", "files/certificate"},
}
for _, file := range files {
fileWriter, err := writer.CreateFormFile(file.fieldName, file.filePath)
assert.NoError(t, err)
f, err := os.Open(file.filePath)
assert.NoError(t, err)
defer f.Close()
_, err = io.Copy(fileWriter, f)
assert.NoError(t, err)
}
writer.Close()
agent := client.Put(url).Body(requestBody.Bytes()).ContentType(writer.FormDataContentType())
agent.Set("Authorization", fmt.Sprintf("Bearer %s", token))
statusCode, respBody, errs := agent.Bytes()
if len(errs) > 0 {
assert.NoError(t, errs[0])
}
assert.Equal(t, 200, statusCode)
fmt.Println(string(respBody))
}

43
tests/helpers/jwt.go Normal file

@ -0,0 +1,43 @@
package helpers
import (
"github.com/dgrijalva/jwt-go"
"penahub.gitlab.yandexcloud.net/backend/penahub_common/jwt_adapter"
"strings"
"time"
)
func CreateJwt(userID string) (string, error) {
var publicKey = strings.Replace(`-----BEGIN PUBLIC KEY-----
MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHgnvr7O2tiApjJfid1orFnIGm69
80fZp+Lpbjo+NC/0whMFga2Biw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6B
dA4TS2kB9Kf0wn0+7wSlyikHoKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y
+3GyaOY536H47qyXAgMBAAE=
-----END PUBLIC KEY-----`, "\t", "", -1)
var privateKey = strings.Replace(`-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgHgnvr7O2tiApjJfid1orFnIGm6980fZp+Lpbjo+NC/0whMFga2B
iw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6BdA4TS2kB9Kf0wn0+7wSlyikH
oKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y+3GyaOY536H47qyXAgMBAAEC
gYAOphnVPXbk6lpYzdkLC1Xn5EOEuNfOLLURLxBnPWozZo26r/Mtahu/9mYhrYlv
PP8r6mxta3VIil8iOdZyOLa/4d1LPd+UehgEXIJEiYXLtn7RS5eUnoPuQxssfs1k
OWjdN8p6SzppleegFTvGRX4KM3cDLfSphOk8JuBCrpSSYQJBAOdqizTSrdKMTuVe
c7Jk1JOJkyFuFs+N5zeryyeFGH7IpRdWy0rkWMxIUAi8Ap1vYVBPHv4tDOo3sy5X
VLc/knkCQQCE62pg+0TmsrhO/2Pgog6MLBkzlzXYMRp/01HbmznwYF+ejfPnzLkz
hnUlxRUNK3lhXM/7H6oAjvqF2R72u/OPAkEAterkmdbQfEZ+MwNoEiH/lie9OLdx
SSI1VGdBYcTYN7qFRW6eizYstBJYkDU0HQ0Uw+we4hMKJwk4W0KdvxxDiQJAeqlB
V1QqBneBbK10PzVuFV8QtrJhJyxRVwrtbKq38iMNuqUnI4+ijXEUpJFWVvv6nKXo
7McQvEk12dU/JNTX8wJAOlAtSNjp9tVwpMpC0w2St1eKc1L2SknjeohA5ldoBz8sGeZsPhTU3eHSD1neAZXLKN5K68z3zFBr20ubY9nyLw==
-----END RSA PRIVATE KEY-----`, "\t", "", -1)
token, err := jwt_adapter.Create(userID, jwt_adapter.ForCreate{
PrivateKey: []byte(privateKey),
PublicKey: []byte(publicKey),
Audience: "pena",
Issuer: "pena-auth-service",
Algorithm: jwt.SigningMethodRS256,
ExpiresIn: 15 * time.Minute,
})
return token, err
}