From c6ba00b74f4e26cfb046ec289ebafdc971a74249 Mon Sep 17 00:00:00 2001 From: Arnaud Delcasse Date: Tue, 2 May 2023 00:34:33 +0200 Subject: [PATCH] Extend PostgreSQL implementation and unit tests on MongoDB storage --- README.md | 11 +- config.go | 11 + go.mod | 25 +- go.sum | 149 ++-------- grpcapi/accounts.go | 14 +- grpcapi/accounts.pb.go | 93 +++--- grpcapi/accounts.proto | 13 +- grpcapi/comasvc.pb.go | 2 +- grpcapi/comasvc_grpc.pb.go | 2 +- handlers/accounts.go | 48 +-- storage/accounts.go | 14 +- storage/mongodb.go | 13 +- storage/mongodb_test.go | 118 ++++++++ storage/postgresql.go | 533 ++++++++++++++++++---------------- storage/postgresql/schema.hcl | 81 ++++++ storage/postgresql_test.go | 418 +++++++++----------------- storage/storage.go | 10 +- storage/storage_test.go | 67 +++++ 18 files changed, 870 insertions(+), 752 deletions(-) create mode 100644 storage/mongodb_test.go create mode 100644 storage/postgresql/schema.hcl create mode 100644 storage/storage_test.go diff --git a/README.md b/README.md index 1438427..3a59281 100755 --- a/README.md +++ b/README.md @@ -130,8 +130,17 @@ The OIDC provider needs [Etcd v3](https://etcd.io/) (see below for storage consi COOPGO Mobility Accounts supports the following databases for storage : - [x] MongoDB +- [x] PostgreSQL -Feel free to contribute any other storage option. +#### SQL schema + +SQL schema for PostgreSQL is available from file `storage/postgresql/schema.hcl` in the [atlasgo Data Definition Language](https://atlasgo.io/getting-started) format + +To set your development DB with this schema easily, you can simply use atlasgo CLI : + +``` +atlas schema apply --url "postgresql://username:password@localhost:5432/coopgo_platform?sslmode=disable" +``` ### OpenID Connect provider diff --git a/config.go b/config.go index df563e8..83a099e 100755 --- a/config.go +++ b/config.go @@ -21,6 +21,17 @@ func ReadConfig() (*viper.Viper, error) { "users": "users", }, }, + "psql": map[string]any{ + "host": "localhost", + "port": "5432", + "dbname": "coopgo_platform", + "sslmode": "disable", + "schema": "mobilityaccounts", + "tables": map[string]any{ + "accounts": "accounts", + "accounts_auth_local": "accounts_auth_local", + }, + }, }, "kv": map[string]any{ "type": "etcd", diff --git a/go.mod b/go.mod index 468d1d8..6f936e8 100755 --- a/go.mod +++ b/go.mod @@ -3,9 +3,11 @@ module git.coopgo.io/coopgo-platform/mobility-accounts go 1.18 require ( + ariga.io/atlas v0.10.1 github.com/google/uuid v1.3.0 github.com/gorilla/csrf v1.7.1 github.com/gorilla/mux v1.8.0 + github.com/hashicorp/hcl/v2 v2.16.2 github.com/lib/pq v1.10.2 github.com/mitchellh/mapstructure v1.5.0 github.com/ory/fosite v0.42.2 @@ -20,31 +22,28 @@ require ( ) require ( + github.com/agext/levenshtein v1.2.1 // indirect + github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgraph-io/ristretto v0.0.3 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-stack/stack v1.8.0 // indirect + github.com/go-openapi/inflect v0.19.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.1 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/gorilla/securecookie v1.1.1 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/jackc/chunkreader/v2 v2.0.1 // indirect - github.com/jackc/pgconn v1.14.0 // indirect - github.com/jackc/pgio v1.0.0 // indirect - github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgproto3/v2 v2.3.2 // indirect - github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect - github.com/jackc/pgtype v1.14.0 // indirect - github.com/jackc/pgx/v4 v4.18.1 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/goveralls v0.0.6 // indirect + github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect github.com/ory/go-acc v0.2.6 // indirect @@ -55,16 +54,20 @@ require ( github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/cobra v1.0.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/testify v1.8.2 // indirect github.com/subosito/gotenv v1.4.2 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.1 // indirect github.com/xdg-go/stringprep v1.0.3 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect + github.com/zclconf/go-cty v1.12.1 // indirect go.etcd.io/etcd/api/v3 v3.5.6 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.6 // indirect go.uber.org/atomic v1.9.0 // indirect @@ -73,8 +76,8 @@ require ( golang.org/x/net v0.6.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect - golang.org/x/tools v0.1.12 // indirect + golang.org/x/text v0.8.0 // indirect + golang.org/x/tools v0.6.0 // indirect google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index f290c5a..1111776 100755 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +ariga.io/atlas v0.10.1 h1:zub8+r1P4OqUYoDl6AgUxqPRwl8A9oeI5q3LucfsnUE= +ariga.io/atlas v0.10.1/go.mod h1:+TR129FJZ5Lvzms6dvCeGWh1yR6hMvmXBhug4hrNIGk= bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -42,10 +44,10 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DataDog/datadog-go v4.0.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= @@ -56,6 +58,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= +github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -64,6 +68,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= +github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= @@ -73,6 +79,7 @@ github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0 github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/aws/aws-sdk-go v1.23.19/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-xray-sdk-go v0.9.4/go.mod h1:XtMKdBQfpVut+tJEwI7+dJFRxxRdxHDyVNp2tHXRq04= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -94,11 +101,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/cockroachdb/cockroach-go v0.0.0-20190925194419-606b3d062051/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= @@ -158,7 +161,6 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= @@ -169,8 +171,6 @@ github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzP github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -199,6 +199,8 @@ github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.0/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= +github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= @@ -244,8 +246,8 @@ github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbN github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/attrs v0.1.0/go.mod h1:fmNpaWyHM0tRm8gCZWKx8yY9fvaNLo2PyzBNSrBZ5Hw= github.com/gobuffalo/buffalo v0.12.8-0.20181004233540-fac9bb505aa8/go.mod h1:sLyT7/dceRXJUxSsE813JTQtA3Eb1vjxWfo/N//vXIY= @@ -497,7 +499,6 @@ github.com/gobuffalo/x v0.0.0-20181007152206-913e47c59ca7/go.mod h1:9rDPXaB3kXdK github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v3.1.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid/v3 v3.1.2/go.mod h1:xPwMqoocQ1L5G6pXX5BcE7N5jlzn2o19oqAKxwZW/kI= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -555,9 +556,8 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-jsonnet v0.16.0/go.mod h1:sOcuej3UW1vpPTZOr8L7RQimqai1a57bt5j22LzGZCw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -614,16 +614,16 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcl/v2 v2.16.2 h1:mpkHZh/Tv+xet3sy3F9Ld4FyI2tUpWe9x3XtPx9f1a0= +github.com/hashicorp/hcl/v2 v2.16.2/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6KocSLCMCXng= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inhies/go-bytesize v0.0.0-20201103132853-d0aed0d254f8/go.mod h1:KrtyD5PFj++GKkFS/7/RRrfnRhAMGQwy75GLCHWrCNs= -github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= @@ -632,19 +632,9 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.3.2/go.mod h1:LvCquS3HbBKwgl7KbX9KyqEIumJAbm1UMcTvGaIf3bM= github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= github.com/jackc/pgconn v1.6.0/go.mod h1:yeseQo4xhQbgyJs2c87RAXOH2i624N0Fh1KSPJya7qo= -github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= -github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= -github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.14.0 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q= -github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E= -github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= -github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= -github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= @@ -652,38 +642,22 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvW github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.0.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0= -github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= github.com/jackc/pgtype v1.3.0/go.mod h1:b0JqxHvPmljG+HQ5IsvQ0yqeSi4nGcDTVjFoiLDb0Ik= -github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw= -github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= -github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o= github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.4.1/go.mod h1:6iSW+JznC0YT+SgBn7rNxoEBsBgSmnC5FwyCekOGUiE= github.com/jackc/pgx/v4 v4.6.0/go.mod h1:vPh43ZzxijXUVJ+t/EmXBtFmbFVO72cuneCT9oAlxAg= -github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0= -github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jandelgado/gcov2lcov v1.0.4-0.20210120124023-b83752c6dc08/go.mod h1:NnSxK6TMlg1oGDBfGelGbjgorT5/L3cchlbtgFYZSss= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -739,11 +713,11 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= @@ -753,8 +727,6 @@ github.com/luna-duclos/instrumentedsql v1.1.3/go.mod h1:9J1njvFds+zN7y85EDhN9XNQ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -808,6 +780,8 @@ github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00v github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -832,7 +806,7 @@ github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/oleiade/reflections v1.0.0/go.mod h1:RbATFBbKYkVdqmSFtx13Bb/tVhR0lgOBXunWTZKeL4w= +github.com/oleiade/reflections v1.0.0/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60= github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM= github.com/oleiade/reflections v1.0.1/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -898,8 +872,6 @@ github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAv github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= -github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= @@ -972,9 +944,9 @@ github.com/segmentio/go-snakecase v1.1.0/go.mod h1:jk1miR5MS7Na32PZUykG89Arm+1BU github.com/segmentio/objconv v1.0.1/go.mod h1:auayaH5k3137Cl4SoXTgrzQcuQDmvuVtZgS0fb1Ahys= github.com/serenize/snaker v0.0.0-20171204205717-a683aaf2d516/go.mod h1:Yow6lPLSAXx2ifx470yD/nUe22Dv5vBvxK/UK9UUTVs= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= @@ -1005,8 +977,6 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B github.com/spf13/afero v1.2.0/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.3.2/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= -github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= @@ -1034,8 +1004,6 @@ github.com/spf13/viper v1.2.1/go.mod h1:P4AexN0a+C9tGAnUFNwDMYYZv3pjFuvmeiMyKRaN github.com/spf13/viper v1.3.1/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= -github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518/go.mod h1:CKI4AZ4XmGV240rTHfO0hfE83S6/a3/Q1siZJ/vXf7A= @@ -1045,6 +1013,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -1052,15 +1021,14 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= 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.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.1.1/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI= -github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/tidwall/gjson v1.3.2/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= @@ -1088,12 +1056,8 @@ github.com/unrolled/secure v0.0.0-20181005190816-ff9db2ff917f/go.mod h1:mnPT77IA github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= @@ -1109,7 +1073,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zclconf/go-cty v1.12.1 h1:PcupnljUm9EIvbgSHQnHhUr3fO6oFmkOrvs2BAFNXXY= +github.com/zclconf/go-cty v1.12.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= go.elastic.co/apm v1.8.0/go.mod h1:tCw6CkOJgkWnzEthFN9HUP1uL3Gjc/Ur6m7gRPLaoH0= @@ -1117,24 +1082,16 @@ go.elastic.co/apm/module/apmhttp v1.8.0/go.mod h1:9LPFlEON51/lRbnWDfqAWErihIiAFD go.elastic.co/apm/module/apmot v1.8.0/go.mod h1:Q5Xzabte8G/fkvDjr1jlDuOSUt9hkVWNZEHh6ZNaTjI= go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd/api/v3 v3.5.4 h1:OHVyt3TopwtUQ2GKdd5wu3PmmipR4FTwCqoEjSyRdIc= -go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/api/v3 v3.5.6 h1:Cy2qx3npLcYqTKqGJzMypnMv2tiRyifZJ17BlWIWA7A= go.etcd.io/etcd/api/v3 v3.5.6/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= -go.etcd.io/etcd/client/pkg/v3 v3.5.4 h1:lrneYvz923dvC14R54XcA7FXoZ3mlGZAgmwhfm7HqOg= -go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/pkg/v3 v3.5.6 h1:TXQWYceBKqLp4sa87rcPs11SXxUA/mHwH975v+BDvLU= go.etcd.io/etcd/client/pkg/v3 v3.5.6/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= -go.etcd.io/etcd/client/v3 v3.5.4 h1:p83BUL3tAYS0OT/r0qglgc3M1JjhM0diV8DSWAhVXv4= -go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= go.etcd.io/etcd/client/v3 v3.5.6 h1:coLs69PWCXE9G4FKquzNaSHrRyMCAXwF+IX1tAPVO8E= go.etcd.io/etcd/client/v3 v3.5.6/go.mod h1:f6GRinRMCsFVv9Ht42EyY7nfsVGwrNO0WEoS2pRKzQk= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= -go.mongodb.org/mongo-driver v1.9.1 h1:m078y9v7sBItkt1aaoe2YlvWEXcD263e1a4E1fBrJ1c= -go.mongodb.org/mongo-driver v1.9.1/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= go.mongodb.org/mongo-driver v1.11.4 h1:4ayjakA013OdpGyL2K3ZqylTac/rMjrJOMZ1EHizXas= go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -1153,26 +1110,18 @@ go.opentelemetry.io/otel/trace v0.18.0/go.mod h1:FzdUu3BPwZSZebfQ1vl5/tAa8LyMLXS go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= @@ -1213,14 +1162,8 @@ golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= @@ -1263,10 +1206,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180816102801-aaf60122140d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1321,9 +1262,6 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 h1:NWy5+hlRbC7HK+PmcXVUmW1IMyFce7to56IUvhUFm7Y= -golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1336,7 +1274,6 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1349,10 +1286,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= -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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1438,17 +1372,11 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/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-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1457,10 +1385,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1520,7 +1447,6 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1529,7 +1455,6 @@ golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191224055732-dd894d0a8a40/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1562,18 +1487,16 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.6.2/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= @@ -1649,8 +1572,6 @@ google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd h1:e0TwkXOdbnH/1x5rc5MZ/VYyiZ4v+RdVfrGMqEwT68I= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef h1:uQ2vjV/sHTsWSqdKeLqmwitzgvjMl7o4IdtHwUDXSJY= google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1677,9 +1598,6 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk= google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/grpc/examples v0.0.0-20210304020650-930c79186c99/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= @@ -1695,9 +1613,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/DataDog/dd-trace-go.v1 v1.27.0/go.mod h1:Sp1lku8WJMvNV0kjDI4Ni/T7J/U3BO5ct5kEaoVU8+I= @@ -1720,8 +1635,6 @@ gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:a gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4= -gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 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/mail.v2 v2.0.0-20180731213649-a0242b2233b4/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= @@ -1747,8 +1660,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= diff --git a/grpcapi/accounts.go b/grpcapi/accounts.go index 1a6ac68..e28c188 100755 --- a/grpcapi/accounts.go +++ b/grpcapi/accounts.go @@ -10,9 +10,10 @@ import ( ) func (a Account) ToStorageType() storage.Account { - var localauth storage.LocalAuth + var localauth *storage.LocalAuth if a.Authentication != nil && a.Authentication.Local != nil { - localauth = a.Authentication.Local.ToStorageType() + la := a.Authentication.Local.ToStorageType() + localauth = &la } account := storage.Account{ ID: a.Id, @@ -42,12 +43,12 @@ func (lc LocalAuth) ToStorageType() storage.LocalAuth { Username: lc.Username, Password: lc.Password, Email: lc.Email, - EmailValidation: storage.Validation{ + EmailValidation: &storage.Validation{ Validated: lc.EmailValidation.Validated, ValidationCode: lc.EmailValidation.ValidationCode, }, PhoneNumber: lc.PhoneNumber, - PhoneNumberValidation: storage.Validation{ + PhoneNumberValidation: &storage.Validation{ Validated: lc.PhoneNumberValidation.Validated, ValidationCode: lc.PhoneNumberValidation.ValidationCode, }, @@ -55,7 +56,10 @@ func (lc LocalAuth) ToStorageType() storage.LocalAuth { } func AccountFromStorageType(account *storage.Account) (*Account, error) { - lc := LocalAuthFromStorageType(account.Authentication.Local) + var lc *LocalAuth + if account.Authentication.Local != nil { + lc = LocalAuthFromStorageType(*account.Authentication.Local) + } d, err := sanitizeData(account.Data) if err != nil { diff --git a/grpcapi/accounts.pb.go b/grpcapi/accounts.pb.go index 3c35093..c223f42 100755 --- a/grpcapi/accounts.pb.go +++ b/grpcapi/accounts.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.28.0 -// protoc v3.19.4 +// protoc v3.19.6 // source: accounts.proto package grpcapi @@ -97,7 +97,7 @@ type AccountAuth struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Local *LocalAuth `protobuf:"bytes,7,opt,name=local,proto3" json:"local,omitempty"` + Local *LocalAuth `protobuf:"bytes,7,opt,name=local,proto3,oneof" json:"local,omitempty"` //TODO SSO } func (x *AccountAuth) Reset() { @@ -144,12 +144,12 @@ type LocalAuth struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Username string `protobuf:"bytes,10,opt,name=username,proto3" json:"username,omitempty"` + Username *string `protobuf:"bytes,10,opt,name=username,proto3,oneof" json:"username,omitempty"` Password string `protobuf:"bytes,11,opt,name=password,proto3" json:"password,omitempty"` - Email string `protobuf:"bytes,12,opt,name=email,proto3" json:"email,omitempty"` - PhoneNumber string `protobuf:"bytes,13,opt,name=phone_number,json=phoneNumber,proto3" json:"phone_number,omitempty"` - EmailValidation *Validation `protobuf:"bytes,14,opt,name=email_validation,json=emailValidation,proto3" json:"email_validation,omitempty"` - PhoneNumberValidation *Validation `protobuf:"bytes,15,opt,name=phone_number_validation,json=phoneNumberValidation,proto3" json:"phone_number_validation,omitempty"` + Email *string `protobuf:"bytes,12,opt,name=email,proto3,oneof" json:"email,omitempty"` + PhoneNumber *string `protobuf:"bytes,13,opt,name=phone_number,json=phoneNumber,proto3,oneof" json:"phone_number,omitempty"` + EmailValidation *Validation `protobuf:"bytes,14,opt,name=email_validation,json=emailValidation,proto3,oneof" json:"email_validation,omitempty"` + PhoneNumberValidation *Validation `protobuf:"bytes,15,opt,name=phone_number_validation,json=phoneNumberValidation,proto3,oneof" json:"phone_number_validation,omitempty"` } func (x *LocalAuth) Reset() { @@ -185,8 +185,8 @@ func (*LocalAuth) Descriptor() ([]byte, []int) { } func (x *LocalAuth) GetUsername() string { - if x != nil { - return x.Username + if x != nil && x.Username != nil { + return *x.Username } return "" } @@ -199,15 +199,15 @@ func (x *LocalAuth) GetPassword() string { } func (x *LocalAuth) GetEmail() string { - if x != nil { - return x.Email + if x != nil && x.Email != nil { + return *x.Email } return "" } func (x *LocalAuth) GetPhoneNumber() string { - if x != nil { - return x.PhoneNumber + if x != nil && x.PhoneNumber != nil { + return *x.PhoneNumber } return "" } @@ -296,35 +296,44 @@ var file_accounts_proto_rawDesc = []byte{ 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x2f, 0x0a, 0x0b, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x05, 0x6c, 0x6f, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3e, 0x0a, 0x0b, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x12, 0x25, 0x0a, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x4c, 0x6f, 0x63, 0x61, - 0x6c, 0x41, 0x75, 0x74, 0x68, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0xf9, 0x01, 0x0a, - 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, - 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, - 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x68, 0x6f, 0x6e, - 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x10, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x0f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x43, 0x0a, 0x17, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x15, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x53, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x42, 0x39, 0x5a, - 0x37, 0x67, 0x69, 0x74, 0x2e, 0x63, 0x6f, 0x6f, 0x70, 0x67, 0x6f, 0x2e, 0x69, 0x6f, 0x2f, 0x63, - 0x6f, 0x6f, 0x70, 0x67, 0x6f, 0x2d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x6d, - 0x6f, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, - 0x2f, 0x67, 0x72, 0x70, 0x63, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x41, 0x75, 0x74, 0x68, 0x48, 0x00, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x88, 0x01, + 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0xeb, 0x02, 0x0a, 0x09, + 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x19, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x88, 0x01, + 0x01, 0x12, 0x26, 0x0a, 0x0c, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x0b, 0x70, 0x68, 0x6f, 0x6e, 0x65, + 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x3b, 0x0a, 0x10, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x48, 0x03, 0x52, 0x0f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x48, 0x0a, 0x17, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x5f, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x04, 0x52, 0x15, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, + 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x08, 0x0a, + 0x06, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x70, 0x68, 0x6f, 0x6e, + 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x1a, 0x0a, + 0x18, 0x5f, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x53, 0x0a, 0x0a, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x42, 0x39, + 0x5a, 0x37, 0x67, 0x69, 0x74, 0x2e, 0x63, 0x6f, 0x6f, 0x70, 0x67, 0x6f, 0x2e, 0x69, 0x6f, 0x2f, + 0x63, 0x6f, 0x6f, 0x70, 0x67, 0x6f, 0x2d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, + 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x73, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -415,6 +424,8 @@ func file_accounts_proto_init() { } } } + file_accounts_proto_msgTypes[1].OneofWrappers = []interface{}{} + file_accounts_proto_msgTypes[2].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/grpcapi/accounts.proto b/grpcapi/accounts.proto index 0291280..b8dceb3 100755 --- a/grpcapi/accounts.proto +++ b/grpcapi/accounts.proto @@ -12,16 +12,17 @@ message Account { } message AccountAuth { - LocalAuth local = 7; + optional LocalAuth local = 7; + //TODO SSO } message LocalAuth { - string username = 10; + optional string username = 10; string password = 11; - string email = 12; - string phone_number = 13; - Validation email_validation = 14; - Validation phone_number_validation = 15; + optional string email = 12; + optional string phone_number = 13; + optional Validation email_validation = 14; + optional Validation phone_number_validation = 15; } message Validation { diff --git a/grpcapi/comasvc.pb.go b/grpcapi/comasvc.pb.go index fb73b45..8a08b59 100755 --- a/grpcapi/comasvc.pb.go +++ b/grpcapi/comasvc.pb.go @@ -3,7 +3,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.28.0 -// protoc v3.19.4 +// protoc v3.19.6 // source: comasvc.proto package grpcapi diff --git a/grpcapi/comasvc_grpc.pb.go b/grpcapi/comasvc_grpc.pb.go index 4e68b0c..518f392 100755 --- a/grpcapi/comasvc_grpc.pb.go +++ b/grpcapi/comasvc_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.2.0 -// - protoc v3.19.4 +// - protoc v3.19.6 // source: comasvc.proto package grpcapi diff --git a/handlers/accounts.go b/handlers/accounts.go index 815a8d7..436cc89 100755 --- a/handlers/accounts.go +++ b/handlers/accounts.go @@ -17,7 +17,8 @@ func (h MobilityAccountsHandler) Login(username string, password string, namespa if password == "" { return nil, errors.New("empty password not allowed") } - account, err := h.storage.DB.LocalAuthentication(namespace, strings.ToLower(username), "", "") + u := strings.ToLower(username) + account, err := h.storage.DB.LocalAuthentication(namespace, &u, nil, nil) if err != nil { return nil, err } @@ -33,25 +34,34 @@ func (h MobilityAccountsHandler) Register(account storage.Account) (*storage.Acc return nil, errors.New("id should be empty") } - account.Authentication.Local.Username = strings.ToLower(account.Authentication.Local.Username) - account.Authentication.Local.Email = strings.ToLower(account.Authentication.Local.Email) - - _, err := h.storage.DB.LocalAuthentication(account.Namespace, account.Authentication.Local.Username, account.Authentication.Local.Email, account.Authentication.Local.PhoneNumber) - - if err == nil { - return nil, errors.New("user already exists") - } - // Generate new UUID account.ID = uuid.NewString() - // If a password was sent, hash the password - if account.Authentication.Local.Password != "" { - hashedPassword, err := bcrypt.GenerateFromPassword([]byte(account.Authentication.Local.Password), bcrypt.DefaultCost) - if err != nil { - return nil, err + if account.Authentication.Local != nil && account.Authentication.Local.Username != nil { + username := strings.ToLower(*account.Authentication.Local.Username) + account.Authentication.Local.Username = &username + } + if account.Authentication.Local != nil && account.Authentication.Local.Email != nil { + email := strings.ToLower(*account.Authentication.Local.Email) + account.Authentication.Local.Username = &email + } + + //TODO remove this as we want to handle unicity in storage + if account.Authentication.Local != nil { + // If a password was sent, hash the password + if account.Authentication.Local.Password != "" { + hashedPassword, err := bcrypt.GenerateFromPassword([]byte(account.Authentication.Local.Password), bcrypt.DefaultCost) + if err != nil { + return nil, err + } + account.Authentication.Local.Password = string(hashedPassword) + } + + _, err := h.storage.DB.LocalAuthentication(account.Namespace, account.Authentication.Local.Username, account.Authentication.Local.Email, account.Authentication.Local.PhoneNumber) + + if err == nil { + return nil, errors.New("user already exists") } - account.Authentication.Local.Password = string(hashedPassword) } // Validate data schemas @@ -131,13 +141,13 @@ func (h MobilityAccountsHandler) UpdatePhoneNumber(accountid, phone_number strin return err } - account2, err := h.storage.DB.LocalAuthentication(account.Namespace, "", "", phone_number) + account2, err := h.storage.DB.LocalAuthentication(account.Namespace, nil, nil, &phone_number) if err == nil && account.ID != account2.ID { return errors.New("user with this phone number already exists") } - account.Authentication.Local.PhoneNumber = phone_number + account.Authentication.Local.PhoneNumber = &phone_number account.Authentication.Local.PhoneNumberValidation.Validated = verified account.Authentication.Local.PhoneNumberValidation.ValidationCode = verification_code @@ -155,7 +165,7 @@ func (h MobilityAccountsHandler) GetAccount(id string) (account *storage.Account } func (h MobilityAccountsHandler) GetAccountUsername(username string, namespace string) (account *storage.Account, err error) { - account, err = h.storage.DB.LocalAuthentication(namespace, username, "", "") + account, err = h.storage.DB.LocalAuthentication(namespace, &username, nil, nil) return } diff --git a/storage/accounts.go b/storage/accounts.go index 2a6a256..7f1017d 100755 --- a/storage/accounts.go +++ b/storage/accounts.go @@ -9,17 +9,17 @@ type Account struct { } type AccountAuth struct { - Local LocalAuth + Local *LocalAuth `bson:"local,omitempty"` //TODO handle SSO } type LocalAuth struct { - Username string `json:"username"` - Password string `json:"password"` - Email string `json:"email"` - EmailValidation Validation `json:"email_validation" bson:"email_validation"` - PhoneNumber string `json:"phone_number" bson:"phone_number"` - PhoneNumberValidation Validation `json:"phone_number_validation" bson:"phone_number_validation"` + Username *string `json:"username" bson:"username,omitempty"` + Password string `json:"password" bson:"password"` + Email *string `json:"email" bson:"email,omitempty"` + EmailValidation *Validation `json:"email_validation" bson:"email_validation,omitempty"` + PhoneNumber *string `json:"phone_number" bson:"phone_number,omitempty"` + PhoneNumberValidation *Validation `json:"phone_number_validation" bson:"phone_number_validation,omitempty"` } type Validation struct { diff --git a/storage/mongodb.go b/storage/mongodb.go index 3b543e5..70a5896 100755 --- a/storage/mongodb.go +++ b/storage/mongodb.go @@ -65,20 +65,20 @@ func NewMongoDBStorage(cfg *viper.Viper) (MongoDBStorage, error) { // If username, is provided (not an empty string), it will search by username only // If username is an empty string and email is provided, it will search by email // If both username and email are empty strings, phone_number must be provided and it will search by phone number -func (s MongoDBStorage) LocalAuthentication(namespace string, username string, email string, phone_number string) (*Account, error) { +func (s MongoDBStorage) LocalAuthentication(namespace string, username *string, email *string, phone_number *string) (*Account, error) { collection := s.Client.Database(s.DbName).Collection(s.Collections["users"]) account := &Account{} - if username != "" { + if username != nil { if err := collection.FindOne(context.TODO(), bson.M{"namespace": namespace, "authentication.local.username": username}).Decode(account); err != nil { return nil, err } - } else if email != "" { + } else if email != nil { if err := collection.FindOne(context.TODO(), bson.M{"namespace": namespace, "authentication.local.email": email}).Decode(account); err != nil { return nil, err } - } else if phone_number != "" { + } else if phone_number != nil { if err := collection.FindOne(context.TODO(), bson.M{"namespace": namespace, "authentication.local.phone_number": phone_number}).Decode(account); err != nil { return nil, err } @@ -191,3 +191,8 @@ func (s MongoDBStorage) UpdateAccount(account Account) error { return nil } + +func (s MongoDBStorage) Migrate() error { + fmt.Println("no migration") + return nil +} diff --git a/storage/mongodb_test.go b/storage/mongodb_test.go new file mode 100644 index 0000000..71883c2 --- /dev/null +++ b/storage/mongodb_test.go @@ -0,0 +1,118 @@ +package storage + +import ( + "testing" + + "github.com/google/uuid" + "github.com/spf13/viper" + "github.com/stretchr/testify/require" +) + +var cfg2 *viper.Viper + +func init() { + cfg2 = viper.New() + cfg2.SetDefault("storage.db.mongodb.host", "localhost") + cfg2.SetDefault("storage.db.mongodb.port", "27017") + cfg2.SetDefault("storage.db.mongodb.user", "mongodb") + cfg2.SetDefault("storage.db.mongodb.db_name", "mobilityaccounts_tests") + cfg2.SetDefault("storage.db.mongodb.sslmode", "disable") + cfg2.SetDefault("storage.db.mongodb.collections.users", "users") + cfg2.SetConfigName("config") // Define values in config.yaml + cfg2.AddConfigPath(".") + cfg2.ReadInConfig() +} + +func TestMongoDBStorage_CreateAndGetAccount(t *testing.T) { + db, err := NewMongoDBStorage(cfg2) + require.NoError(t, err) + err = db.CreateAccount(account1) + require.NoError(t, err) + + result, err := db.GetAccount(account1.ID) + require.NoError(t, err) + + require.Equal(t, &account1, result) +} +func TestMongoDBStorage_CreateAndGetAccountNoAuth(t *testing.T) { + db, err := NewMongoDBStorage(cfg2) + require.NoError(t, err) + + err = db.CreateAccount(account3) + require.NoError(t, err) + + result, err := db.GetAccount(account3.ID) + require.NoError(t, err) + + require.Equal(t, &account3, result) +} + +func TestMongoDBStorage_UpdateAccount(t *testing.T) { + db, err := NewMongoDBStorage(cfg2) + require.NoError(t, err) + + err = db.CreateAccount(account2) + require.NoError(t, err) + + modified := account2 + modified.Authentication.Local.Email = Ptr("modifiedtest@test.com") + modified.Data["key1"] = "modeifiedvalue" + modified.Data["addedkey"] = "addedvalue" + modified.Metadata["addedmetadatakey"] = "addedmetadatavalue" + err = db.UpdateAccount(modified) + require.NoError(t, err) + + result, err := db.GetAccount(account2.ID) + require.NoError(t, err) + + require.Equal(t, &modified, result) +} + +func TestMongoDBStorage_LocalAuthentication(t *testing.T) { + db, err := NewMongoDBStorage(cfg2) + require.NoError(t, err) + + _, err = db.LocalAuthentication(account1.Namespace, account1.Authentication.Local.Username, nil, nil) + require.NoError(t, err) + + _, err = db.LocalAuthentication(account1.Namespace, nil, account1.Authentication.Local.Email, nil) + require.NoError(t, err) + + _, err = db.LocalAuthentication(account1.Namespace, nil, nil, account1.Authentication.Local.PhoneNumber) + require.NoError(t, err) +} + +func TestMongoDBStorage_GetAccounts(t *testing.T) { + db, err := NewMongoDBStorage(cfg2) + require.NoError(t, err) + + accounts, err := db.GetAccounts([]string{account1.Namespace, account3.Namespace}) + require.NoError(t, err) + + for _, account := range accounts { + require.Contains(t, []string{account1.Namespace, account3.Namespace}, account.Namespace) + } +} + +func TestMongoDBsqlStorage_GetAccountsByIds(t *testing.T) { + db, err := NewMongoDBStorage(cfg2) + require.NoError(t, err) + + accounts, err := db.GetAccountsByIds([]string{account2.ID, account3.ID}) + require.NoError(t, err) + + for _, account := range accounts { + require.Contains(t, []string{account2.ID, account3.ID}, account.ID) + } +} + +func TestMongoDBStorage_CreateAlreadyExistingCredentials(t *testing.T) { + db, err := NewMongoDBStorage(cfg2) + require.NoError(t, err) + + modified := account1 + modified.ID = uuid.NewString() // Change the ID to make as if it was a new one + + err = db.CreateAccount(modified) + require.Error(t, err) +} diff --git a/storage/postgresql.go b/storage/postgresql.go index 47beb70..77e8042 100644 --- a/storage/postgresql.go +++ b/storage/postgresql.go @@ -1,39 +1,40 @@ -/* - ___ ___ ___ _ __ __ _ ___ - / __/ _ \ / _ \| '_ \ / _` |/ _ \ -| (_| (_) | (_) | |_) | (_| | (_) | - \___\___/ \___/| .__/ \__, |\___/ - | | __/ | - |_| |___/ -*/ - package storage import ( + "context" "database/sql" "encoding/json" "fmt" - _ "github.com/lib/pq" - "github.com/spf13/viper" + "os" "strconv" "strings" + + "ariga.io/atlas/sql/postgres" + "ariga.io/atlas/sql/schema" + "github.com/lib/pq" + _ "github.com/lib/pq" + "github.com/spf13/viper" ) type PostgresqlStorage struct { DbConnection *sql.DB + Tables map[string]string } func NewPostgresqlStorage(cfg *viper.Viper) (PostgresqlStorage, error) { var ( - host = cfg.GetString("storage.db.psql.host") - port = cfg.GetString("storage.db.psql.port") - user = cfg.GetString("storage.db.psql.user") - password = cfg.GetString("storage.db.psql.password") - dbname = cfg.GetString("storage.db.psql.dbname") + host = cfg.GetString("storage.db.psql.host") + port = cfg.GetString("storage.db.psql.port") + user = cfg.GetString("storage.db.psql.user") + password = cfg.GetString("storage.db.psql.password") + dbname = cfg.GetString("storage.db.psql.dbname") + sslmode = cfg.GetString("storage.db.psql.sslmode") + pg_schema = cfg.GetString("storage.db.psql.schema") + pgtables_accounts = cfg.GetString("storage.db.psql.tables.accounts") + pgtables_accounts_auth_local = cfg.GetString("storage.db.psql.tables.accounts_auth_local") ) portInt, _ := strconv.Atoi(port) - psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", host, portInt, - user, password, dbname) + psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s", host, portInt, user, password, dbname, sslmode) db, err := sql.Open("postgres", psqlconn) if err != nil { fmt.Println("error", err) @@ -41,10 +42,15 @@ func NewPostgresqlStorage(cfg *viper.Viper) (PostgresqlStorage, error) { } err = db.Ping() if err != nil { + fmt.Println(err) return PostgresqlStorage{}, fmt.Errorf("connection to postgresql database failed") } return PostgresqlStorage{ DbConnection: db, + Tables: map[string]string{ + "accounts": fmt.Sprintf("%s.%s", pg_schema, pgtables_accounts), + "accounts_auth_local": fmt.Sprintf("%s.%s", pg_schema, pgtables_accounts_auth_local), + }, }, nil } @@ -53,29 +59,91 @@ func (psql PostgresqlStorage) GetAccount(id string) (*Account, error) { data, metadata, emailValidation, phoneValidation []byte ) account := &Account{} - stmtAccounts, err := psql.DbConnection.Prepare("" + - "SELECT id, namespace, data, " + - "metadata, username, password, email, email_validation, " + - "phone_number, phone_number_validation FROM accounts a JOIN " + - "account_auth auth ON id = account_id WHERE id = $1") - if err != nil { - return nil, fmt.Errorf("psql connection failed") - } - defer stmtAccounts.Close() - err = stmtAccounts.QueryRow(id).Scan(&account.ID, + + var username, password, email, phonenumber *string + + req := fmt.Sprintf(`SELECT id, namespace, data, metadata, username, password, email, email_validation, phone_number, phone_number_validation + FROM %s a + LEFT JOIN %s auth ON id = account_id WHERE id = $1`, psql.Tables["accounts"], psql.Tables["accounts_auth_local"]) + err := psql.DbConnection.QueryRow(req, id).Scan(&account.ID, &account.Namespace, &data, &metadata, + &username, + &password, + &email, + &emailValidation, + &phonenumber, + &phoneValidation) + if err != nil { + return nil, fmt.Errorf("psql select account query failed : %s", err) + } + + err = json.Unmarshal(data, &account.Data) + if err != nil { + return nil, err + } + err = json.Unmarshal(metadata, &account.Metadata) + if err != nil { + return nil, err + } + + if password != nil || username != nil || email != nil || phonenumber != nil { + account.Authentication.Local = &LocalAuth{ + Username: username, + Password: *password, + Email: email, + PhoneNumber: phonenumber, + } + err = json.Unmarshal(emailValidation, &account.Authentication.Local.EmailValidation) + if err != nil { + return nil, err + } + err = json.Unmarshal(phoneValidation, &account.Authentication.Local.PhoneNumberValidation) + if err != nil { + return nil, err + } + } + + return account, nil +} + +func (psql PostgresqlStorage) LocalAuthentication(namespace string, username *string, email *string, phone_number *string) (*Account, error) { + account := &Account{} + var ( + data, metadata, emailValidation, phoneValidation []byte + ) + + requested_field := "" + requested_value := "" + if username != nil { + requested_field = "username" + requested_value = *username + } else if email != nil { + requested_field = "email" + requested_value = *email + } else if phone_number != nil { + requested_field = "phone_number" + requested_value = *phone_number + } else { + return nil, fmt.Errorf("localauthentication func error PSQL") + } + + req := fmt.Sprintf(`SELECT id, namespace, data, metadata, username, password, email, email_validation, phone_number, phone_number_validation + FROM %s INNER JOIN %s ON id = account_id + WHERE account_namespace = $1 AND %s = $2;`, psql.Tables["accounts"], psql.Tables["accounts_auth_local"], requested_field) + + account.Authentication.Local = &LocalAuth{} + err := psql.DbConnection.QueryRow(req, namespace, requested_value).Scan( + &account.ID, + &account.Namespace, &data, &metadata, &account.Authentication.Local.Username, &account.Authentication.Local.Password, &account.Authentication.Local.Email, &emailValidation, &account.Authentication.Local.PhoneNumber, &phoneValidation) - if err != nil { - return nil, fmt.Errorf("psql select account query failed") - } - err = json.Unmarshal(data, &account.Data) + if err != nil { return nil, err } @@ -83,6 +151,10 @@ func (psql PostgresqlStorage) GetAccount(id string) (*Account, error) { if err != nil { return nil, err } + err = json.Unmarshal(data, &account.Data) + if err != nil { + return nil, err + } err = json.Unmarshal(emailValidation, &account.Authentication.Local.EmailValidation) if err != nil { return nil, err @@ -94,142 +166,15 @@ func (psql PostgresqlStorage) GetAccount(id string) (*Account, error) { return account, nil } -func (psql PostgresqlStorage) LocalAuthentication(namespace string, username string, email string, - phone_number string) (*Account, error) { - account := &Account{} - var ( - data, metadata, emailValidation, phoneValidation []byte - ) - if username != "" { - usernameStmt, err := psql.DbConnection.Prepare("SELECT id, namespace, data, metadata, username, " + - "password, email, email_validation, phone_number, phone_number_validation " + - "FROM accounts INNER JOIN account_auth ON accounts.id = account_auth.account_id WHERE " + - "namespace = $1 AND username = $2;") - if err != nil { - return nil, err - } - err = usernameStmt.QueryRow(namespace, username).Scan( - &account.ID, - &account.Namespace, &data, &metadata, - &account.Authentication.Local.Username, - &account.Authentication.Local.Password, - &account.Authentication.Local.Email, - &emailValidation, &account.Authentication.Local.PhoneNumber, - &phoneValidation) - if err != nil { - return nil, err - } - err = json.Unmarshal(metadata, &account.Metadata) - if err != nil { - return nil, err - } - err = json.Unmarshal(data, &account.Data) - if err != nil { - return nil, err - } - err = json.Unmarshal(emailValidation, &account.Authentication.Local.EmailValidation) - if err != nil { - return nil, err - } - err = json.Unmarshal(phoneValidation, &account.Authentication.Local.PhoneNumberValidation) - if err != nil { - return nil, err - } - return account, nil - } else if email != "" { - account.Authentication.Local.Email = email - emailStmt, err := psql.DbConnection.Prepare("SELECT id, namespace, data, metadata, username, " + - "password, email_validation, phone_number, phone_number_validation " + - "FROM accounts INNER JOIN account_auth ON " + - "accounts.id = account_auth.account_id WHERE namespace = $1 AND email = $2;") - if err != nil { - return nil, err - } - err = emailStmt.QueryRow(namespace, email).Scan( - &account.ID, - &account.Namespace, - &data, &metadata, - &account.Authentication.Local.Username, - &account.Authentication.Local.Password, - &emailValidation, - &account.Authentication.Local.PhoneNumber, - &phoneValidation) - if err != nil { - return nil, err - } - err = json.Unmarshal(metadata, &account.Metadata) - if err != nil { - return nil, err - } - err = json.Unmarshal(data, &account.Data) - if err != nil { - return nil, err - } - err = json.Unmarshal(emailValidation, &account.Authentication.Local.EmailValidation) - if err != nil { - return nil, err - } - err = json.Unmarshal(phoneValidation, &account.Authentication.Local.PhoneNumberValidation) - if err != nil { - return nil, err - } - return account, nil - } else if phone_number != "" { - account.Authentication.Local.PhoneNumber = phone_number - phoneStmt, err := psql.DbConnection.Prepare("SELECT id, namespace, " + - "data, metadata, username, password, email, " + - "email_validation, phone_number_validation FROM accounts " + - "INNER JOIN account_auth ON accounts.id = account_auth.account_id WHERE " + - "namespace = $1 AND phone_number = $2;") - if err != nil { - return nil, err - } - err = phoneStmt.QueryRow(namespace, phone_number).Scan(&account.ID, - &account.Namespace, - &data, - &metadata, - &account.Authentication.Local.Username, - &account.Authentication.Local.Password, - &account.Authentication.Local.Email, - &emailValidation, - &phoneValidation) - if err != nil { - return nil, err - } - err = json.Unmarshal(metadata, &account.Metadata) - if err != nil { - return nil, err - } - err = json.Unmarshal(data, &account.Data) - if err != nil { - return nil, err - } - err = json.Unmarshal(emailValidation, &account.Authentication.Local.EmailValidation) - if err != nil { - return nil, err - } - err = json.Unmarshal(phoneValidation, &account.Authentication.Local.PhoneNumberValidation) - if err != nil { - return nil, err - } - return account, nil - } - return nil, fmt.Errorf("localauthentication func error PSQL") -} - func (psql PostgresqlStorage) GetAccounts(namespaces []string) ([]Account, error) { var accounts []Account namespacesStr := "'" + strings.Join(namespaces, "', '") + "'" query := ` - SELECT accounts.id, accounts.namespace, accounts.data, accounts.metadata, - account_auth.username, account_auth.password, - account_auth.email, account_auth.email_validation, - account_auth.phone_number, account_auth.phone_number_validation - FROM accounts - INNER JOIN account_auth ON accounts.id = account_auth.account_id - WHERE accounts.namespace IN (%s) + SELECT id, namespace, data, metadata, username, password, email, email_validation, phone_number, phone_number_validation + FROM %s LEFT JOIN %s ON id = account_id + WHERE namespace IN (%s) ` - query = fmt.Sprintf(query, namespacesStr) + query = fmt.Sprintf(query, psql.Tables["accounts"], psql.Tables["accounts_auth_local"], namespacesStr) rows, err := psql.DbConnection.Query(query) if err != nil { return nil, err @@ -239,19 +184,20 @@ func (psql PostgresqlStorage) GetAccounts(namespaces []string) ([]Account, error var account Account var dataBytes []byte var metadataBytes []byte - var emailValidationBytes []byte - var phoneNumberValidationBytes []byte + var emailValidation []byte + var phoneValidation []byte + var username, password, email, phonenumber *string err := rows.Scan( &account.ID, &account.Namespace, &dataBytes, &metadataBytes, - &account.Authentication.Local.Username, - &account.Authentication.Local.Password, - &account.Authentication.Local.Email, - &emailValidationBytes, - &account.Authentication.Local.PhoneNumber, - &phoneNumberValidationBytes, + &username, + &password, + &email, + &emailValidation, + &phonenumber, + &phoneValidation, ) if err != nil { return nil, err @@ -266,14 +212,22 @@ func (psql PostgresqlStorage) GetAccounts(namespaces []string) ([]Account, error if err != nil { return nil, err } - err = json.Unmarshal(emailValidationBytes, &account.Authentication.Local.EmailValidation) - if err != nil { - return nil, err - } - err = json.Unmarshal(phoneNumberValidationBytes, &account.Authentication.Local.PhoneNumberValidation) - if err != nil { - return nil, err + if password != nil || username != nil || email != nil || phonenumber != nil { + account.Authentication.Local = &LocalAuth{ + Username: username, + Password: *password, + Email: email, + PhoneNumber: phonenumber, + } + err = json.Unmarshal(emailValidation, &account.Authentication.Local.EmailValidation) + if err != nil { + return nil, err + } + err = json.Unmarshal(phoneValidation, &account.Authentication.Local.PhoneNumberValidation) + if err != nil { + return nil, err + } } accounts = append(accounts, account) } @@ -282,18 +236,15 @@ func (psql PostgresqlStorage) GetAccounts(namespaces []string) ([]Account, error func (psql PostgresqlStorage) GetAccountsByIds(accountids []string) ([]Account, error) { var accounts []Account - accountIdsStr := "'" + strings.Join(accountids, "', '") + "'" + query := ` - SELECT accounts.id, accounts.namespace, accounts.data, accounts.metadata, - account_auth.username, account_auth.password, - account_auth.email, account_auth.email_validation, - account_auth.phone_number, account_auth.phone_number_validation - FROM accounts - INNER JOIN account_auth ON accounts.id = account_auth.account_id - WHERE accounts.id IN (%s) + SELECT id, namespace, data, metadata, username, password, email, email_validation, phone_number, phone_number_validation + FROM %s + LEFT JOIN %s ON id = account_id + WHERE id = ANY ($1) ` - query = fmt.Sprintf(query, accountIdsStr) - rows, err := psql.DbConnection.Query(query) + query = fmt.Sprintf(query, psql.Tables["accounts"], psql.Tables["accounts_auth_local"]) //, accountIdsStr) + rows, err := psql.DbConnection.Query(query, pq.Array(accountids)) if err != nil { return nil, err } @@ -302,19 +253,21 @@ func (psql PostgresqlStorage) GetAccountsByIds(accountids []string) ([]Account, var account Account var dataBytes []byte var metadataBytes []byte - var emailValidationBytes []byte - var phoneNumberValidationBytes []byte + var emailValidation []byte + var phoneValidation []byte + var username, password, email, phonenumber *string err := rows.Scan( &account.ID, &account.Namespace, &dataBytes, &metadataBytes, - &account.Authentication.Local.Username, - &account.Authentication.Local.Password, - &account.Authentication.Local.Email, - &emailValidationBytes, - &account.Authentication.Local.PhoneNumber, - &phoneNumberValidationBytes) + &username, + &password, + &email, + &emailValidation, + &phonenumber, + &phoneValidation, + ) if err != nil { return nil, err } @@ -329,14 +282,21 @@ func (psql PostgresqlStorage) GetAccountsByIds(accountids []string) ([]Account, return nil, err } - err = json.Unmarshal(emailValidationBytes, &account.Authentication.Local.EmailValidation) - if err != nil { - return nil, err - } - - err = json.Unmarshal(phoneNumberValidationBytes, &account.Authentication.Local.PhoneNumberValidation) - if err != nil { - return nil, err + if password != nil || username != nil || email != nil || phonenumber != nil { + account.Authentication.Local = &LocalAuth{ + Username: username, + Password: *password, + Email: email, + PhoneNumber: phonenumber, + } + err = json.Unmarshal(emailValidation, &account.Authentication.Local.EmailValidation) + if err != nil { + return nil, err + } + err = json.Unmarshal(phoneValidation, &account.Authentication.Local.PhoneNumberValidation) + if err != nil { + return nil, err + } } accounts = append(accounts, account) } @@ -344,11 +304,6 @@ func (psql PostgresqlStorage) GetAccountsByIds(accountids []string) ([]Account, } func (psql PostgresqlStorage) CreateAccount(account Account) error { - insertAccountStmt, err := psql.DbConnection.Prepare("INSERT INTO accounts (id, namespace, data, metadata)" + - " VALUES ($1, $2, $3, $4)") - if err != nil { - return err - } dataAccountJson, err := json.Marshal(account.Data) if err != nil { return err @@ -357,43 +312,67 @@ func (psql PostgresqlStorage) CreateAccount(account Account) error { if err != nil { return err } + + tx, err := psql.DbConnection.BeginTx(context.Background(), nil) + if err != nil { + return err + } + defer tx.Rollback() + + insertAccountStmt, err := tx.Prepare(fmt.Sprintf("INSERT INTO %s (id, namespace, data, metadata) VALUES ($1, $2, $3, $4)", psql.Tables["accounts"])) + if err != nil { + return err + } + defer insertAccountStmt.Close() _, err = insertAccountStmt.Exec(account.ID, account.Namespace, dataAccountJson, metadataAccountJson) if err != nil { return err } - insertAccountAuthStmt, err := psql.DbConnection.Prepare("INSERT INTO account_auth (account_id, username," + - " password, email, email_validation,phone_number,phone_number_validation) " + - "values($1, $2, $3, $4, $5, $6, $7)") - if err != nil { - return err + + if account.Authentication.Local != nil { + + emailValidationJson, err := json.Marshal(account.Authentication.Local.EmailValidation) + if err != nil { + return err + } + phoneValidationJson, err := json.Marshal(account.Authentication.Local.PhoneNumberValidation) + if err != nil { + return err + } + insertAccountAuthStmt, err := tx.Prepare(fmt.Sprintf(`INSERT INTO %s (account_id, account_namespace, username, password, email, email_validation, phone_number, phone_number_validation) + VALUES($1, $2, $3, $4, $5, $6, $7, $8);`, psql.Tables["accounts_auth_local"])) + if err != nil { + return err + } + defer insertAccountAuthStmt.Close() + _, err = insertAccountAuthStmt.Exec(account.ID, + account.Namespace, + account.Authentication.Local.Username, + account.Authentication.Local.Password, + account.Authentication.Local.Email, + emailValidationJson, + account.Authentication.Local.PhoneNumber, + phoneValidationJson) + if err != nil { + return err + } + } - emailValidationJson, err := json.Marshal(account.Authentication.Local.EmailValidation) - if err != nil { - return err - } - phoneValidationJson, err := json.Marshal(account.Authentication.Local.PhoneNumberValidation) - if err != nil { - return err - } - _, err = insertAccountAuthStmt.Exec(account.ID, - account.Authentication.Local.Username, - account.Authentication.Local.Password, - account.Authentication.Local.Email, - emailValidationJson, - account.Authentication.Local.PhoneNumber, - phoneValidationJson) - if err != nil { + + if err := tx.Commit(); err != nil { return err } return nil } func (psql PostgresqlStorage) UpdateAccount(account Account) error { - updateAccountStmt, err := psql.DbConnection.Prepare("update accounts set namespace=$1, data=$2, " + - " metadata=$3 where id= $4") + + tx, err := psql.DbConnection.BeginTx(context.Background(), nil) if err != nil { return err } + defer tx.Rollback() + dataAccountJson, err := json.Marshal(account.Data) if err != nil { return err @@ -402,33 +381,77 @@ func (psql PostgresqlStorage) UpdateAccount(account Account) error { if err != nil { return err } - _, err = updateAccountStmt.Exec(account.Namespace, dataAccountJson, metadataAccountJson, account.ID) + + req := fmt.Sprintf("UPDATE %s SET namespace=$1, data=$2, metadata=$3 where id= $4", psql.Tables["accounts"]) + _, err = tx.Exec(req, account.Namespace, dataAccountJson, metadataAccountJson, account.ID) if err != nil { return err } - updateAccountAuthStmt, err := psql.DbConnection.Prepare("update account_auth set username = $1," + - " password = $2," + - " email = $3, email_validation = $4 ," + - "phone_number = $5,phone_number_validation = $6 where account_id = $7") - if err != nil { - return err - } - emailValidationJson, err := json.Marshal(account.Authentication.Local.EmailValidation) - if err != nil { - return err - } - phoneValidationJson, err := json.Marshal(account.Authentication.Local.PhoneNumberValidation) - if err != nil { - return err - } - _, err = updateAccountAuthStmt.Exec(account.Authentication.Local.Username, - account.Authentication.Local.Password, - account.Authentication.Local.Email, - emailValidationJson, - account.Authentication.Local.PhoneNumber, - phoneValidationJson, account.ID) - if err != nil { + + if account.Authentication.Local != nil { + emailValidationJson, err := json.Marshal(account.Authentication.Local.EmailValidation) + if err != nil { + return err + } + phoneValidationJson, err := json.Marshal(account.Authentication.Local.PhoneNumberValidation) + if err != nil { + return err + } + + req = fmt.Sprintf(`UPDATE %s + SET username = $1, password = $2, email = $3, email_validation = $4, + phone_number = $5,phone_number_validation = $6 where account_id = $7`, psql.Tables["accounts_auth_local"]) + _, err = tx.Exec(req, account.Authentication.Local.Username, + account.Authentication.Local.Password, + account.Authentication.Local.Email, + emailValidationJson, + account.Authentication.Local.PhoneNumber, + phoneValidationJson, account.ID) + if err != nil { + return err + } + } + + if err := tx.Commit(); err != nil { return err } + + return nil +} + +func (psql PostgresqlStorage) Migrate() error { + ctx := context.Background() + driver, err := postgres.Open(psql.DbConnection) + if err != nil { + return err + } + + existing, err := driver.InspectRealm(ctx, nil) + if err != nil { + return err + } + + var desired schema.Realm + + hcl, err := os.ReadFile("postgresql/schema.hcl") + if err != nil { + return err + } + + err = postgres.EvalHCLBytes(hcl, &desired, nil) + if err != nil { + return err + } + + diff, err := driver.RealmDiff(existing, &desired) + if err != nil { + return err + } + + err = driver.ApplyChanges(ctx, diff) + if err != nil { + return err + } + return nil } diff --git a/storage/postgresql/schema.hcl b/storage/postgresql/schema.hcl new file mode 100644 index 0000000..969aeb7 --- /dev/null +++ b/storage/postgresql/schema.hcl @@ -0,0 +1,81 @@ +table "accounts" { + schema = schema.mobilityaccounts + column "id" { + null = false + type = uuid + } + column "namespace" { + null = true + type = text + } + column "data" { + null = true + type = jsonb + } + column "metadata" { + null = true + type = jsonb + } + primary_key { + columns = [column.id] + } +} +table "accounts_auth_local" { + schema = schema.mobilityaccounts + column "account_id" { + null = true + type = uuid + } + column "account_namespace" { + null = true + type = text + } + column "username" { + null = true + type = text + } + column "password" { + null = true + type = text + } + column "email" { + null = true + type = text + } + column "email_validation" { + null = true + type = jsonb + } + column "phone_number" { + null = true + type = text + } + column "phone_number_validation" { + null = true + type = jsonb + } + foreign_key "accounts_auth_local_account_id_fkey" { + columns = [column.account_id] + ref_columns = [table.accounts.column.id] + on_update = NO_ACTION + on_delete = NO_ACTION + } + index "accounts_auth_local_account_id_key" { + unique = true + columns = [column.account_id] + } + index "accounts_auth_local_idx_email" { + unique = true + columns = [column.account_namespace, column.email] + } + index "accounts_auth_local_idx_phone_number" { + unique = true + columns = [column.account_namespace, column.phone_number] + } + index "accounts_auth_local_idx_username" { + unique = true + columns = [column.account_namespace, column.username] + } +} +schema "mobilityaccounts" { +} diff --git a/storage/postgresql_test.go b/storage/postgresql_test.go index 6393847..7bdaed8 100644 --- a/storage/postgresql_test.go +++ b/storage/postgresql_test.go @@ -1,279 +1,141 @@ package storage import ( - "crypto/rand" - "encoding/hex" - "encoding/json" + "context" "fmt" - "github.com/spf13/viper" "reflect" "testing" + + "github.com/google/uuid" + _ "github.com/lib/pq" + "github.com/spf13/viper" ) -// Tests must be run in order -// Table creation: -/* ##################################################################################################################### -CREATE TABLE accounts ( - id TEXT PRIMARY KEY, - namespace TEXT, - data JSONB, - metadata JSONB -); - -CREATE TABLE account_auth ( - account_id TEXT PRIMARY KEY, - username TEXT, - password TEXT, - email TEXT, - email_validation JSONB, - phone_number TEXT, - phone_number_validation JSONB, - FOREIGN KEY (account_id) REFERENCES accounts(id) -); -####################################################################################################################### -*/ -/* Inserting an Account: (Password = test) -####################################################################################################################### -INSERT INTO accounts (id, namespace, data, metadata) -VALUES ('2faa137b-27be-476f-b98c-8b7eed6f1f3a', 'parcoursmob', '{"email": "salimbouaram12@gmail.com", "gender": "9", -"groups": ["483280d0-db2d-4f06-b361-02e4be5012d2", "483280d0-db2d-4f06-b361-02e4be5012d2:admin"], "last_name": "salim", -"first_name": "salim", "display_name": "salim salim", "phone_number": ""}', '{"created": "2023-04-24T09:29:18.262+00:00"}'); -####################################################################################################################### -INSERT INTO account_auth (account_id, username, password, email, email_validation, phone_number, phone_number_validation) -VALUES ('2faa137b-27be-476f-b98c-8b7eed6f1f3a', 'salim-amine.bou-aram@coopgo.fr', -'$2a$10$j9LwkGYT6HhLpWxUvpEniOJ3nBKEhwAn52G.t4QYMgje4HnJuWqHK', 'salim-amine.bou-aram@coopgo.fr', -'{"validated": false, "validation_code": ""}', '0749331953', '{"validated": false, "validation_code": ""}'); -####################################################################################################################### -*/ - var cfg *viper.Viper func init() { cfg = viper.New() - cfg.Set("storage.db.psql.host", "localhost") - cfg.Set("storage.db.psql.port", "5432") - cfg.Set("storage.db.psql.user", "postgres") - cfg.Set("storage.db.psql.password", "postgres") - cfg.Set("storage.db.psql.dbname", "mobilityaccounts") + cfg.SetDefault("storage.db.psql.host", "localhost") + cfg.SetDefault("storage.db.psql.port", "5432") + cfg.SetDefault("storage.db.psql.user", "postgres") + cfg.SetDefault("storage.db.psql.password", "postgres") + cfg.SetDefault("storage.db.psql.dbname", "mobilityaccounts_tests") + cfg.SetDefault("storage.db.psql.sslmode", "disable") + cfg.SetDefault("storage.db.psql.schema", "mobilityaccounts") + cfg.SetDefault("storage.db.psql.tables.accounts", "accounts") + cfg.SetDefault("storage.db.psql.tables.accounts_auth_local", "accounts_auth_local") + cfg.SetConfigName("config") // Override default values in a config.yaml file within this directory + cfg.AddConfigPath(".") + cfg.ReadInConfig() } -func TestNewPostgresqlStorage(t *testing.T) { +func TestPostgresqlStorage_Initialize(t *testing.T) { storage, err := NewPostgresqlStorage(cfg) - storage.DbConnection.Exec("Delete from account_auth ;") - storage.DbConnection.Exec("Delete from accounts ;") if err != nil { t.Errorf("error creating new PostgreSQL storage: %v", err) } defer storage.DbConnection.Close() -} -func generateUUIDv4() string { - uuid := make([]byte, 16) - _, err := rand.Read(uuid) + err = storage.Migrate() if err != nil { - panic(err) + t.Errorf("database migration issue: %v", err) + return + } + + tx, err := storage.DbConnection.BeginTx(context.Background(), nil) + if err != nil { + t.Errorf("transaction issue: %v", err) + return + } + defer tx.Rollback() + _, err = tx.Exec(fmt.Sprintf("DELETE FROM %s;", storage.Tables["accounts_auth_local"])) + if err != nil { + t.Errorf("delete accounts table issue: %v", err) + return + } + _, err = tx.Exec(fmt.Sprintf("DELETE FROM %s;", storage.Tables["accounts"])) + if err != nil { + t.Errorf("delete accounts table issue: %v", err) + return + } + if err = tx.Commit(); err != nil { + t.Errorf("commit transaction issue: %v", err) + return } - uuid[6] = (uuid[6] & 0x0f) | 0x40 - uuid[8] = (uuid[8] & 0xbf) | 0x80 - return hex.EncodeToString(uuid[:4]) + "-" + hex.EncodeToString(uuid[4:6]) + "-" + - hex.EncodeToString(uuid[6:8]) + "-" + hex.EncodeToString(uuid[8:10]) + "-" + - hex.EncodeToString(uuid[10:]) } -func TestGetAccount(t *testing.T) { - // Open a database connection +func TestPostgresqlStorage_CreateAndGetAccount(t *testing.T) { db, err := NewPostgresqlStorage(cfg) - Id := generateUUIDv4() if err != nil { t.Errorf("failed to create new psql connection") } - // Insert data into accounts table - accountData := map[string]any{ - "key1": "value1", - "key2": "value2", - } - accountMetadata := map[string]any{ - "key1": "value1", - "key2": "value2", - } - account := Account{ - ID: Id, - Namespace: "test_namespace", - Data: accountData, - Metadata: accountMetadata, - } - dataJSON, err := json.Marshal(map[string]any{ - "key1": "value1", - "key2": "value2", - }) + err = db.CreateAccount(account1) if err != nil { - t.Errorf("error account data and metdata") + t.Errorf("Failed to create account : %s", err) + return } - _, err = db.DbConnection.Exec("INSERT INTO accounts (id, namespace, data, metadata) "+ - "VALUES ($1, $2, $3, $4)", account.ID, account.Namespace, dataJSON, dataJSON) + + result, err := db.GetAccount(account1.ID) if err != nil { - t.Errorf("error in inserting a new account") + t.Errorf("Failed to get account : %s", err) + return } - // Insert data into account_auth table - emailValidation := Validation{ - Validated: true, - ValidationCode: "code", - } - localAuth := LocalAuth{ - Username: "testuser", - Password: "testpassword", - Email: "test@test.com", - EmailValidation: emailValidation, - PhoneNumber: "1234567890", - PhoneNumberValidation: emailValidation, - } - localAuthJSON, err := json.Marshal(emailValidation) - if err != nil { - t.Errorf("error account_auth localAuth") - } - _, err = db.DbConnection.Exec("INSERT INTO account_auth (account_id, username, password, "+ - "email, email_validation, "+ - "phone_number,phone_number_validation) VALUES ($1, $2, $3, $4, $5, $6, $7)", account.ID, - localAuth.Username, localAuth.Password, localAuth.Email, localAuthJSON, localAuth.PhoneNumber, localAuthJSON) - if err != nil { - fmt.Println(err) - t.Errorf("error in iserting a new account in account_auth") - } - account_, err := db.GetAccount(Id) - if err != nil { - t.Errorf("failed") - fmt.Println(err) - } - expectedAccount := &Account{ - ID: Id, - Namespace: "test_namespace", - Data: accountData, - Metadata: accountMetadata, - Authentication: AccountAuth{ - Local: localAuth, - }, - } - if reflect.DeepEqual(account_, expectedAccount) { - fmt.Println("PASS") - } else { - t.Errorf("The received account is not the same as expected") + + if !reflect.DeepEqual(&account1, result) { + t.Errorf("The received account is not the same as expected\nSaved Account : %v\nRetrieved Account : %v", &account1, result) } } -func TestPostgresqlStorage_CreateAccount(t *testing.T) { +func TestPostgresqlStorage_CreateAndGetAccountNoAuth(t *testing.T) { db, err := NewPostgresqlStorage(cfg) - Id := generateUUIDv4() if err != nil { t.Errorf("failed to create new psql connection") } - emailValidation := Validation{ - Validated: true, - ValidationCode: "code", - } - localAuth := LocalAuth{ - Username: "salim", - Password: "testpassword", - Email: "test@test.com", - EmailValidation: emailValidation, - PhoneNumber: "1234567890", - PhoneNumberValidation: emailValidation, - } - accountData := map[string]any{ - "key1": "value1", - "key2": "value2", - } - accountMetadata := map[string]any{ - "key1": "value1", - "key2": "value2", - } - account := Account{ - ID: Id, - Namespace: "namespace", - Authentication: AccountAuth{ - Local: localAuth, - }, - Data: accountData, - Metadata: accountMetadata, - } - err = db.CreateAccount(account) + err = db.CreateAccount(account3) if err != nil { - fmt.Println(err) - t.Errorf("Failed to create account") + t.Errorf("Failed to create account : %s", err) + return + } + + result, err := db.GetAccount(account3.ID) + if err != nil { + t.Errorf("Failed to get account : %s", err) + return + } + + if !reflect.DeepEqual(&account3, result) { + t.Errorf("The received account is not the same as expected\nSaved Account : %v\nRetrieved Account : %v", &account3, result) } } func TestPostgresqlStorage_UpdateAccount(t *testing.T) { db, err := NewPostgresqlStorage(cfg) - Id := generateUUIDv4() if err != nil { t.Errorf("failed to create new psql connection") } - emailValidation := Validation{ - Validated: true, - ValidationCode: "code", - } - localAuth := LocalAuth{ - Username: "salim", - Password: "testpassword", - Email: "test@test.com", - EmailValidation: emailValidation, - PhoneNumber: "1234567890", - PhoneNumberValidation: emailValidation, - } - accountData := map[string]any{ - "key1": "value1", - "key2": "value2", - } - accountMetadata := map[string]any{ - "key1": "value1", - "key2": "value2", - } - account := Account{ - ID: Id, - Namespace: "test_namespace", - Authentication: AccountAuth{ - Local: localAuth, - }, - Data: accountData, - Metadata: accountMetadata, - } - err = db.CreateAccount(account) + err = db.CreateAccount(account2) if err != nil { - fmt.Println(err) - t.Errorf("Failed to create account") + t.Errorf("Failed to create account : %s", err) + return } - account2 := Account{ - ID: Id, - Namespace: "salim", - Authentication: AccountAuth{ - Local: LocalAuth{ - Username: "salim", - Password: "salim", - Email: "salim@test.com", - EmailValidation: Validation{ - Validated: false, - ValidationCode: "123", - }, - PhoneNumber: "12345", - PhoneNumberValidation: Validation{ - Validated: true, - ValidationCode: "1233", - }, - }, - }, - Data: map[string]any{ - "key1": "salim1", - "key2": "salim2", - }, - Metadata: map[string]any{ - "key1": "salim1", - "key2": "salim2", - }, - } - err = db.UpdateAccount(account2) + modified := account2 + modified.Authentication.Local.Email = Ptr("modifiedtest@test.com") + modified.Data["key1"] = "modeifiedvalue" + modified.Data["addedkey"] = "addedvalue" + modified.Metadata["addedmetadatakey"] = "addedmetadatavalue" + err = db.UpdateAccount(modified) if err != nil { - fmt.Println(err) - t.Errorf("failed") + t.Errorf("failed updating account : %s", err) + } + + result, err := db.GetAccount(account2.ID) + if err != nil { + t.Errorf("Failed to get account : %s", err) + return + } + + if !reflect.DeepEqual(&modified, result) { + t.Errorf("The received account is not the same as expected\nSaved Account : %v\nRetrieved Account : %v", &modified, result) } } @@ -282,30 +144,18 @@ func TestPostgresqlStorage_LocalAuthentication(t *testing.T) { if err != nil { t.Errorf("failed to create new psql connection") } - accountByUsername, err := db.LocalAuthentication("test_namespace", "testuser", - "", "") + _, err = db.LocalAuthentication(account1.Namespace, account1.Authentication.Local.Username, nil, nil) if err != nil { - t.Errorf("Failed LocalAuthentication based on username and namespace") + t.Errorf("Failed LocalAuthentication based on username and namespace : %s", err) } - fmt.Println(accountByUsername) - accountByEmail, err := db.LocalAuthentication("test_namespace", "", - "test@test.com", "") + _, err = db.LocalAuthentication(account1.Namespace, nil, account1.Authentication.Local.Email, nil) if err != nil { - t.Errorf("Failed LocalAuthentication based on username and namespace") + t.Errorf("Failed LocalAuthentication based on email and namespace :\n Namespace: %s\n Email: %s\nError: %s", account1.Namespace, *account1.Authentication.Local.Email, err) } - fmt.Println(accountByEmail) - accountByPhone, err := db.LocalAuthentication("test_namespace", "", - "", "1234567890") + _, err = db.LocalAuthentication(account1.Namespace, nil, nil, account1.Authentication.Local.PhoneNumber) if err != nil { - t.Errorf("Failed LocalAuthentication based on username and namespace") + t.Errorf("Failed LocalAuthentication based on phone number and namespace :\n Namespace: %s\n Phone number: %s\nError: %s", account1.Namespace, *account1.Authentication.Local.PhoneNumber, err) } - fmt.Println(accountByPhone) - accountByAll, err := db.LocalAuthentication("test_namespace", "testuser", - "test@test.com", "1234567890") - if err != nil { - t.Errorf("Failed LocalAuthentication based on username and namespace") - } - fmt.Println(accountByAll) } func TestPostgresqlStorage_GetAccounts(t *testing.T) { @@ -313,12 +163,15 @@ func TestPostgresqlStorage_GetAccounts(t *testing.T) { if err != nil { t.Errorf("failed to create new psql connection") } - accounts, err := db.GetAccounts([]string{"test_namespace", "salim", "namespace"}) + accounts, err := db.GetAccounts([]string{account1.Namespace, account3.Namespace}) if err != nil { - t.Errorf("Failed") + t.Errorf("Failed : %s", err) + return } for _, account := range accounts { - fmt.Println(account) + if account.Namespace != account1.Namespace && account.Namespace != account3.Namespace { + t.Errorf("This namespace was not requested : %s", account.Namespace) + } } } @@ -326,44 +179,47 @@ func TestPostgresqlStorage_GetAccountsByIds(t *testing.T) { db, err := NewPostgresqlStorage(cfg) if err != nil { t.Errorf("failed to create new psql connection") + return } - account := Account{ - ID: "772315f1-8113-486a-90c7-9073410065bd", - Namespace: "oo", - Authentication: AccountAuth{ - Local: LocalAuth{ - Username: "username", - Password: "password", - Email: "salim@test.com", - EmailValidation: Validation{ - Validated: true, - ValidationCode: "123", - }, - PhoneNumber: "12345", - PhoneNumberValidation: Validation{ - Validated: true, - ValidationCode: "1233", - }, - }, - }, - Data: map[string]any{ - "key1": "salim1", - "key2": "salim2", - }, - Metadata: map[string]any{ - "key1": "salim1", - "key2": "salim2", - }, - } - err = db.CreateAccount(account) + + accounts, err := db.GetAccountsByIds([]string{account2.ID, account3.ID}) if err != nil { - t.Errorf("Failed to create account") + t.Errorf("Failed to get account by ID : %s", err) + return } - accounts, err := db.GetAccountsByIds([]string{"772315f1-8113-486a-90c7-9073410065bd"}) - if err != nil { - t.Errorf("Failed to get account by ID") + + found2 := false + found3 := false + for _, account := range accounts { + if account.ID == account2.ID { + found2 = true + } else if account.ID == account3.ID { + found3 = true + } else { + t.Errorf("This id was not requested : %s", account.ID) + } } - for _, acc := range accounts { - fmt.Println(acc) + if !found2 { + t.Errorf("account id not found for account2 : %s", account2.ID) + } + if !found3 { + t.Errorf("account id not found for account3 : %s", account3.ID) + } +} + +func TestPostgresqlStorage_CreateAlreadyExistingCredentials(t *testing.T) { + db, err := NewPostgresqlStorage(cfg) + if err != nil { + t.Errorf("failed to create new psql connection") + return + } + + modified := account1 + modified.ID = uuid.NewString() // Change the ID to make as if it was a new one + + err = db.CreateAccount(modified) + if err == nil { + t.Errorf("account should not be created : unique index violated !") + return } } diff --git a/storage/storage.go b/storage/storage.go index 297221f..7c71466 100755 --- a/storage/storage.go +++ b/storage/storage.go @@ -30,11 +30,15 @@ func NewStorage(cfg *viper.Viper) (Storage, error) { type DBStorage interface { GetAccount(id string) (*Account, error) - LocalAuthentication(namespace string, username string, email string, phone_number string) (*Account, error) + LocalAuthentication(namespace string, username *string, email *string, phone_number *string) (*Account, error) GetAccounts(namespaces []string) ([]Account, error) GetAccountsByIds(accountids []string) ([]Account, error) CreateAccount(account Account) error + + //TODO : remove UpdateAccount, implement UpdateAccountData and UpdateAccountLocalAuthentication UpdateAccount(account Account) error + + Migrate() error } func NewDBStorage(cfg *viper.Viper) (DBStorage, error) { @@ -66,3 +70,7 @@ func NewKVStore(cfg *viper.Viper) (KVStore, error) { kv, err := NewEtcdKVStore(cfg) return kv, err } + +func Ptr[T any](v T) *T { + return &v +} diff --git a/storage/storage_test.go b/storage/storage_test.go new file mode 100644 index 0000000..f3d7173 --- /dev/null +++ b/storage/storage_test.go @@ -0,0 +1,67 @@ +package storage + +import "github.com/google/uuid" + +var account1 = Account{ + ID: uuid.NewString(), + Namespace: "namespace", + Authentication: AccountAuth{ + Local: &LocalAuth{ + Username: Ptr("test"), + Password: "hashedpassword", + Email: Ptr("test@test.com"), + EmailValidation: &Validation{ + Validated: true, + ValidationCode: "", + }, + PhoneNumber: Ptr("+3312345678"), + PhoneNumberValidation: &Validation{ + Validated: true, + ValidationCode: "", + }, + }, + }, + Data: map[string]any{ + "key1": "value1", + "key2": "value2", + }, + Metadata: map[string]any{ + "key1": "value1", + "key2": "value2", + }, +} + +var account2 = Account{ + ID: uuid.NewString(), + Namespace: "test", + Authentication: AccountAuth{ + Local: &LocalAuth{ + Username: Ptr("test2"), + Password: "hashedpassword", + }, + }, + Data: map[string]any{ + "key1": "value3", + "key2": "value4", + }, + Metadata: map[string]any{ + "key1": "value5", + "key2": "value6", + }, +} + +var account3 = Account{ + ID: uuid.NewString(), + Namespace: "other_namespace", + Authentication: AccountAuth{ + Local: nil, + }, + Data: map[string]any{ + "key1": "value3", + "key2": "value4", + }, + Metadata: map[string]any{ + "key1": "value5", + "key2": "value6", + }, +}