diff --git a/changelog/unreleased/ocm-shares-sql-driver.md b/changelog/unreleased/ocm-shares-sql-driver.md new file mode 100644 index 0000000000..99b6c5bd76 --- /dev/null +++ b/changelog/unreleased/ocm-shares-sql-driver.md @@ -0,0 +1,3 @@ +Enhancement: SQL driver for OCM shares + +https://github.com/cs3org/reva/pull/3654 \ No newline at end of file diff --git a/go.mod b/go.mod index 4dbdff2219..f03037ed47 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e github.com/cs3org/go-cs3apis v0.0.0-20230214162720-ac2ceb2ad50e github.com/dgraph-io/ristretto v0.1.1 + github.com/dolthub/go-mysql-server v0.14.0 github.com/eventials/go-tus v0.0.0-20200718001131-45c7ec8f5d59 github.com/gdexlab/go-render v1.0.1 github.com/glpatcern/go-mime v0.0.0-20221026162842-2a8d71ad17a9 @@ -84,12 +85,15 @@ require ( github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40 // indirect + github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dolthub/vitess v0.0.0-20221031111135-9aad77e7b39f // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/fatih/color v1.13.0 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect + github.com/go-kit/kit v0.10.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.2.3 // indirect @@ -99,9 +103,11 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-stack/stack v1.8.1 // indirect + github.com/gocraft/dbr/v2 v2.7.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/flatbuffers v2.0.6+incompatible // indirect github.com/hashicorp/go-immutable-radix v1.0.0 // indirect github.com/hashicorp/go-msgpack v1.1.5 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect @@ -114,6 +120,7 @@ require ( github.com/klauspost/compress v1.15.11 // indirect github.com/klauspost/cpuid/v2 v2.1.0 // indirect github.com/leodido/go-urn v1.2.1 // indirect + github.com/lestrrat-go/strftime v1.0.4 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect @@ -125,6 +132,7 @@ require ( github.com/minio/sha256-simd v1.0.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/mitchellh/hashstructure v1.1.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -136,6 +144,7 @@ require ( github.com/nxadm/tail v1.4.8 // indirect github.com/oklog/run v1.1.0 // indirect github.com/oklog/ulid v1.3.1 // indirect + github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 // indirect github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pkg/term v1.1.0 // indirect @@ -147,6 +156,7 @@ require ( github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/rs/xid v1.4.0 // indirect + github.com/shopspring/decimal v1.2.0 // indirect github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect github.com/sirupsen/logrus v1.9.0 // indirect @@ -155,11 +165,14 @@ require ( go.etcd.io/bbolt v1.3.6 // indirect go.mongodb.org/mongo-driver v1.8.3 // indirect go.opentelemetry.io/otel/metric v0.34.0 // indirect + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/net v0.5.0 // indirect golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect + golang.org/x/tools v0.1.12 // indirect google.golang.org/appengine v1.6.7 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect + gopkg.in/src-d/go-errors.v1 v1.0.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 8c11b51d7c..2e0e02e4a8 100644 --- a/go.sum +++ b/go.sum @@ -153,8 +153,11 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= @@ -166,6 +169,7 @@ github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= @@ -175,7 +179,10 @@ github.com/ReneKroon/ttlcache/v2 v2.11.0 h1:OvlcYFYi941SBN3v9dsDcC2N8vRxyHcCmJb3 github.com/ReneKroon/ttlcache/v2 v2.11.0/go.mod h1:mBxvsNY+BT8qLLd6CuAJubbKo6r0jh3nb5et22bbfGY= 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/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/akamai/AkamaiOPEN-edgegrid-golang v1.1.0/go.mod h1:kX6YddBkXqqywAe8c9LyvgTCyFuZCTMF4cRPQhc3Fy8= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -190,18 +197,22 @@ github.com/andrewmostello/go-tus v0.0.0-20200314041820-904a9904af9a/go.mod h1:XY github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asim/go-micro/plugins/events/nats/v4 v4.0.0-20220118152736-9e0be6c85d75 h1:G5Degn+tmIBpRCD7vPVpCoAol2gd/S7s00z5CWpzp5U= github.com/asim/go-micro/plugins/events/nats/v4 v4.0.0-20220118152736-9e0be6c85d75/go.mod h1:BxrcQ4TPPMevB2udKEAHenQxCUh1xXVItoU2CbvVdcQ= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.20.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= github.com/aws/aws-sdk-go v1.37.27/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= @@ -209,6 +220,7 @@ github.com/aws/aws-sdk-go v1.43.11/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4 github.com/aws/aws-sdk-go v1.44.114/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.199 h1:hYuQmS4zLMJR9v2iOp2UOD6Vi/0V+nwyR/Uhrkrtlbc= github.com/aws/aws-sdk-go v1.44.199/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -227,6 +239,7 @@ github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+Wji github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/c-bata/go-prompt v0.2.5 h1:3zg6PecEywxNn0xiqcXHD96fkbxghD+gdB2tbsYfl+Y= github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= @@ -235,6 +248,7 @@ github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/ceph/go-ceph v0.15.0 h1:ILB3NaLWOtt4u/2d8I8HZTC4Ycm1PsOYVar3IFU1xlo= github.com/ceph/go-ceph v0.15.0/go.mod h1:mafFpf5Vg8Ai8Bd+FAMvKBHLmtdpTXdRP/TNq8XWegY= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= @@ -247,6 +261,7 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -258,6 +273,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH 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/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= @@ -272,14 +289,18 @@ github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkE github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk= github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpu/goacmedns v0.1.1/go.mod h1:MuaouqEhPAHxsbqjgnck5zeghuwBP1dLnPoobeGqugQ= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e h1:tqSPWQeueWTKnJVMJffz4pz0o1WuQxJ28+5x5JgaHD8= @@ -291,6 +312,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deepmap/oapi-codegen v1.3.11/go.mod h1:suMvK7+rKlx3+tpa8ByptmvoXbAV70wERKTOGH3hLp0= +github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8= +github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -303,13 +326,20 @@ github.com/dnsimple/dnsimple-go v0.63.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dolthub/go-mysql-server v0.14.0 h1:Igw9J19cVghGDqifP79TiFpRCawP3aK8O0qfM+s9Z30= +github.com/dolthub/go-mysql-server v0.14.0/go.mod h1:KtpU4Sf7J+SIat/nxoA733QTn3tdL34NtoGxEBFcTsA= +github.com/dolthub/vitess v0.0.0-20221031111135-9aad77e7b39f h1:2sNrQiE4pcdgCNp09RTOsmNeepgN5rL+ep8NF8Faw9U= +github.com/dolthub/vitess v0.0.0-20221031111135-9aad77e7b39f/go.mod h1:oVFIBdqMFEkt4Xz2fzFJBNtzKhDEjwdCF0dzde39iKs= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/ef-ds/deque v1.0.4/go.mod h1:gXDnTC3yqvBcHbq2lcExjtAcVrOnJCbMcZXmuj8Z4tg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -332,6 +362,8 @@ github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -361,6 +393,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= @@ -408,6 +442,8 @@ github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -443,11 +479,14 @@ github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u1 github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.4/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-yaml v1.9.5/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= +github.com/gocraft/dbr/v2 v2.7.2 h1:ccUxMuz6RdZvD7VPhMRRMSS/ECF3gytPhPtcavjktHk= +github.com/gocraft/dbr/v2 v2.7.2/go.mod h1:5bCqyIXO5fYn3jEp/L06QF4K1siFdhxChMjdNu6YJrg= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +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= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -457,9 +496,12 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -502,6 +544,8 @@ github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/flatbuffers v2.0.6+incompatible h1:XHFReMv7nFFusa+CEokzWbzaYocKXI6C7hdU5Kgh9Lw= +github.com/google/flatbuffers v2.0.6+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -540,6 +584,7 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -565,18 +610,23 @@ github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -604,6 +654,7 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -622,12 +673,14 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= 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/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/infobloxopen/infoblox-go-client v1.1.1/go.mod h1:BXiw7S2b9qJoM8MS40vfgCNB2NLHGusk1DtO16BD9zI= github.com/jarcoal/httpmock v1.0.6/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= @@ -641,6 +694,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w= +github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -648,6 +703,7 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -697,13 +753,22 @@ github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8= +github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= +github.com/lestrrat-go/strftime v1.0.4 h1:T1Rb9EPkAhgxKqbcMIPguPq8glqXTA1koF8n9BHElA8= +github.com/lestrrat-go/strftime v1.0.4/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/linode/linodego v0.25.3/go.mod h1:GSBKPpjoQfxEfryoCRcgkuUOCuVtGHWhzI8OMdycNTE= github.com/liquidweb/go-lwApi v0.0.0-20190605172801-52a4864d2738/go.mod h1:0sYF9rMXb0vlG+4SzdiGMXHheCZxjguMq+Zb4S2BfBs= github.com/liquidweb/go-lwApi v0.0.5/go.mod h1:0sYF9rMXb0vlG+4SzdiGMXHheCZxjguMq+Zb4S2BfBs= github.com/liquidweb/liquidweb-cli v0.6.9/go.mod h1:cE1uvQ+x24NGUL75D0QagOFCG8Wdvmwu8aL9TLmA/eQ= github.com/liquidweb/liquidweb-go v1.6.3/go.mod h1:SuXXp+thr28LnjEw18AYtWwIbWMHSUiajPQs8T9c/Rc= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -724,6 +789,7 @@ github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZb github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= @@ -736,6 +802,8 @@ github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.10 h1:MLn+5bFRlWMGoSRmJour3CL1w/qL96mvipqpwQW/Sfk= github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= @@ -771,6 +839,8 @@ github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed/go.mod h1:3rdaFaCv4AyBgu5ALFM0+tSuHrBh6v692nyQe3ikrq0= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0= +github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -797,17 +867,23 @@ github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7P github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/jwt/v2 v2.3.0 h1:z2mA1a7tIf5ShggOFlR1oBPgd6hGqcDYsISxZByUzdI= github.com/nats-io/jwt/v2 v2.3.0/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= github.com/nats-io/nats-server/v2 v2.9.3/go.mod h1:4sq8wvrpbvSzL1n3ZfEYnH4qeUuIl5W990j3kw13rRk= github.com/nats-io/nats-server/v2 v2.9.11 h1:4y5SwWvWI59V5mcqtuoqKq6L9NDUydOP3Ekwuwl8cZI= github.com/nats-io/nats-server/v2 v2.9.11/go.mod h1:b0oVuxSlkvS3ZjMkncFeACGyZohbO4XhSqW1Lt7iRRY= github.com/nats-io/nats-streaming-server v0.25.2 h1:cWjytvYksYPgnXnSocqnRWVrSgLclusnPGBNHQR4SqI= github.com/nats-io/nats-streaming-server v0.25.2/go.mod h1:bRbgx+iCG6EZEXpqVMroRDuCGwR1iW+ta84aEGBaMhI= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= github.com/nats-io/nats.go v1.16.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= github.com/nats-io/nats.go v1.17.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= github.com/nats-io/nats.go v1.19.0 h1:H6j8aBnTQFoVrTGB6Xjd903UMdE7jz6DS4YkmAqgZ9Q= github.com/nats-io/nats.go v1.19.0/go.mod h1:tLqubohF7t4z3du1QDPYJIQQyhb4wl6DhjxEajSI7UA= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= @@ -825,11 +901,16 @@ github.com/nrdcg/porkbun v0.1.1/go.mod h1:JWl/WKnguWos4mjfp4YizvvToigk9qpQwrodOk github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 h1:Yl0tPBa8QPjGmesFh1D0rDy+q1Twx6FyU7VWHi8wZbI= +github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= @@ -841,32 +922,44 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/oracle/oci-go-sdk v24.3.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= github.com/ovh/go-ovh v1.1.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk= github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= @@ -887,6 +980,7 @@ github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= @@ -897,6 +991,7 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= @@ -905,6 +1000,7 @@ github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= @@ -921,6 +1017,7 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= @@ -948,6 +1045,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sacloud/libsacloud v1.36.2/go.mod h1:P7YAOVmnIn3DKHqCZcUKYUXmSwGBm3yS7IBEjKVSrjg= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210127161313-bd30bebeac4f/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= github.com/sciencemesh/meshdirectory-web v1.0.4 h1:1YSctF6PAXhoHUYCaeRTj7rHaF7b3rYrZf2R0VXBIbo= github.com/sciencemesh/meshdirectory-web v1.0.4/go.mod h1:fJSThTS3xf+sTdL0iXQoaQJssLI7tn7DetHMHUl4SRk= @@ -956,6 +1054,8 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX github.com/sethgrid/pester v0.0.0-20190127155807-68a33a018ad0/go.mod h1:Ad7IjTpvzZO8Fl0vh9AzQ+j/jYZfyp2diGwI8m5q+ns= github.com/sethvargo/go-password v0.2.0 h1:BTDl4CC/gjf/axHMaDQtw507ogrXLci6XRiLc7i/UHI= github.com/sethvargo/go-password v0.2.0/go.mod h1:Ym4Mr9JXLBycr02MFuVQ/0JHidNetSgbzutTr3zsYXE= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -978,6 +1078,8 @@ github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:s github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/gunit v1.0.4/go.mod h1:EH5qMBab2UclzXUcpR8b93eHsIlp9u+pDQIRp5DZNzQ= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= @@ -989,10 +1091,14 @@ github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -1020,6 +1126,7 @@ github.com/thanhpk/randstr v1.0.4/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZu github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g= github.com/tus/tusd v1.1.0/go.mod h1:3DWPOdeCnjBwKtv98y5dSws3itPqfce5TVa0s59LRiA= @@ -1029,6 +1136,8 @@ github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqri github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= @@ -1061,8 +1170,10 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t go-micro.dev/v4 v4.3.1-0.20211108085239-0c2041e43908 h1:4ori3xawGl2unFIOQPEgUuHdlrvihc+dsIot7XUzc2k= go-micro.dev/v4 v4.3.1-0.20211108085239-0c2041e43908/go.mod h1:tw47Xfg2YywfPUnglZgXQsSf7p0ST6mQL3v0JooGmSY= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.m3o.com v0.1.0/go.mod h1:p8FdLqZH3R9a0y04qiMNT+clw69d3SxyQPFzCNbDRtk= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= @@ -1096,18 +1207,23 @@ go.step.sm/crypto v0.23.2 h1:XGmQH9Pkpxop47cjYlUhF10L5roPCbu1BCZXopbeW8I= go.step.sm/crypto v0.23.2/go.mod h1:/IXGz8al8k7u7OV0RTWIi8TRVqO2FMyZVpedV+6Da6U= 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.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66vU6XU= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= 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/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1176,6 +1292,7 @@ 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/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +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/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1196,6 +1313,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1309,6 +1427,7 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1322,6 +1441,7 @@ golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1425,6 +1545,7 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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= @@ -1461,6 +1582,8 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/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-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1471,6 +1594,7 @@ golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/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-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1568,6 +1692,7 @@ google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -1678,8 +1803,11 @@ google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -1739,8 +1867,10 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/h2non/gock.v1 v1.0.14/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= @@ -1756,6 +1886,8 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/src-d/go-errors.v1 v1.0.0 h1:cooGdZnCjYbeS1zb1s6pVAAimTdKceRrpn7aKOnNIfc= +gopkg.in/src-d/go-errors.v1 v1.0.0/go.mod h1:q1cBlomlw2FnDBDNGlnh6X0jPihy+QxZfMMNxPCbdYg= gopkg.in/telebot.v3 v3.0.0/go.mod h1:7rExV8/0mDDNu9epSrDm/8j22KLaActH1Tbee6YjzWg= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -1792,3 +1924,5 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/pkg/ocm/share/repository/sql/conversions.go b/pkg/ocm/share/repository/sql/conversions.go new file mode 100644 index 0000000000..6e2bdf64c8 --- /dev/null +++ b/pkg/ocm/share/repository/sql/conversions.go @@ -0,0 +1,281 @@ +// Copyright 2018-2023 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package sql + +import ( + "strconv" + "strings" + + providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1" + userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1" + provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" + "github.com/cs3org/reva/internal/http/services/owncloud/ocs/conversions" + "github.com/cs3org/reva/pkg/ocm/share" +) + +// ShareType is the type of the share. +type ShareType int + +// AccessMethod is method granted by the sharer to access +// the shared resource. +type AccessMethod int + +// Protocol is the protocol the recipient of the share +// uses to access the shared resource. +type Protocol int + +// ShareState is the state of the share. +type ShareState int + +const ( + // ShareTypeUser is used for a share to an user. + ShareTypeUser ShareType = iota + // ShareTypeGroup is used for a share to a group. + ShareTypeGroup +) + +const ( + // ShareStatePending is the state for a pending share. + ShareStatePending ShareState = iota + // ShareStateAccepted is the share for an accepted share. + ShareStateAccepted + // ShareStateRejected is the share for a rejected share. + ShareStateRejected +) + +const ( + // WebDAVAccessMethod indicates an access using WebDAV to the share. + WebDAVAccessMethod AccessMethod = iota + // WebappAccessMethod indicates an access using a collaborative + // application to the share. + WebappAccessMethod + // TransferAccessMethod indicates a share for a transfer. + TransferAccessMethod +) + +const ( + // WebDAVProtocol is the WebDav protocol. + WebDAVProtocol Protocol = iota + // WebappProtcol is the Webapp protocol. + WebappProtcol + // TransferProtocol is the Transfer protocol. + TransferProtocol +) + +func convertFromCS3OCMShareType(shareType ocm.ShareType) ShareType { + switch shareType { + case ocm.ShareType_SHARE_TYPE_USER: + return ShareTypeUser + case ocm.ShareType_SHARE_TYPE_GROUP: + return ShareTypeGroup + } + return -1 +} + +func convertFromCS3OCMShareState(shareState ocm.ShareState) ShareState { + switch shareState { + case ocm.ShareState_SHARE_STATE_ACCEPTED: + return ShareStateAccepted + case ocm.ShareState_SHARE_STATE_PENDING: + return ShareStatePending + case ocm.ShareState_SHARE_STATE_REJECTED: + return ShareStateRejected + } + return -1 +} + +func convertToCS3OCMShareState(state ShareState) ocm.ShareState { + switch state { + case ShareStateAccepted: + return ocm.ShareState_SHARE_STATE_ACCEPTED + case ShareStatePending: + return ocm.ShareState_SHARE_STATE_PENDING + case ShareStateRejected: + return ocm.ShareState_SHARE_STATE_REJECTED + } + return ocm.ShareState_SHARE_STATE_INVALID +} + +type dbShare struct { + ID int + Token string + Prefix string + ItemSource string + Name string + ShareWith string + Owner string + Initiator string + Ctime int + Mtime int + Expiration int + ShareType ShareType +} + +type dbAccessMethod struct { + ShareID string + Type AccessMethod + WebDAVPermissions *int + WebAppViewMode *int +} + +type dbReceivedShare struct { + ID int + Name string + Prefix string + ItemSource string + ShareWith string + Owner string + Initiator string + Ctime int + Mtime int + Expiration int + Type ShareType + State ShareState +} + +type dbProtocol struct { + ID string + ShareID string + Type Protocol + WebDAVURI *string + WebDAVSharedSecret *string + WebDavPermissions *int + WebappURITemplate *string + TransferSourceURI *string + TransferSharedSecret *string + TransferSize *int +} + +func convertFederatedUserID(s string) *userpb.UserId { + split := strings.Split(s, "@") + if len(split) < 2 { + panic("not in the form @") + } + return &userpb.UserId{ + OpaqueId: split[0], + Idp: split[1], + Type: userpb.UserType_USER_TYPE_FEDERATED, + } +} + +func convertToCS3OCMShare(s *dbShare, am []*ocm.AccessMethod) *ocm.Share { + share := &ocm.Share{ + Id: &ocm.ShareId{ + OpaqueId: strconv.Itoa(s.ID), + }, + ResourceId: &provider.ResourceId{ + StorageId: s.Prefix, + OpaqueId: s.ItemSource, + }, + Name: s.Name, + Token: s.Token, + Grantee: &provider.Grantee{ + Type: provider.GranteeType_GRANTEE_TYPE_USER, + Id: &provider.Grantee_UserId{ + UserId: convertFederatedUserID(s.ShareWith), + }, + }, + Owner: &userpb.UserId{ + OpaqueId: s.Owner, + }, + Creator: &userpb.UserId{ + OpaqueId: s.Initiator, + }, + Ctime: &types.Timestamp{ + Seconds: uint64(s.Ctime), + }, + Mtime: &types.Timestamp{ + Seconds: uint64(s.Mtime), + }, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: am, + } + if s.Expiration != 0 { + share.Expiration = &types.Timestamp{ + Seconds: uint64(s.Expiration), + } + } + return share +} + +func convertToCS3OCMReceivedShare(s *dbReceivedShare, p []*ocm.Protocol) *ocm.ReceivedShare { + share := &ocm.ReceivedShare{ + Id: &ocm.ShareId{ + OpaqueId: strconv.Itoa(s.ID), + }, + ResourceId: &provider.ResourceId{ + StorageId: s.Prefix, + OpaqueId: s.ItemSource, + }, + Name: s.Name, + Grantee: &provider.Grantee{ + Type: provider.GranteeType_GRANTEE_TYPE_USER, + Id: &provider.Grantee_UserId{ + UserId: &userpb.UserId{ + OpaqueId: s.ShareWith, + }, + }, + }, + Owner: convertFederatedUserID(s.Owner), + Creator: convertFederatedUserID(s.Initiator), + Ctime: &types.Timestamp{ + Seconds: uint64(s.Ctime), + }, + Mtime: &types.Timestamp{ + Seconds: uint64(s.Mtime), + }, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: convertToCS3OCMShareState(s.State), + Protocols: p, + } + if s.Expiration != 0 { + share.Expiration = &types.Timestamp{ + Seconds: uint64(s.Expiration), + } + } + return share +} + +func convertToCS3AccessMethod(m *dbAccessMethod) *ocm.AccessMethod { + switch m.Type { + case WebDAVAccessMethod: + return share.NewWebDavAccessMethod(conversions.RoleFromOCSPermissions(conversions.Permissions(*m.WebDAVPermissions)).CS3ResourcePermissions()) + case WebappAccessMethod: + return share.NewWebappAccessMethod(providerv1beta1.ViewMode(*m.WebAppViewMode)) + case TransferAccessMethod: + return share.NewTransferAccessMethod() + } + return nil +} + +func convertToCS3Protocol(p *dbProtocol) *ocm.Protocol { + switch p.Type { + case WebDAVProtocol: + return share.NewWebDAVProtocol(*p.WebDAVURI, *p.WebDAVSharedSecret, &ocm.SharePermissions{ + Permissions: conversions.RoleFromOCSPermissions(conversions.Permissions(*p.WebDavPermissions)).CS3ResourcePermissions(), + }) + case WebappProtcol: + return share.NewWebappProtocol(*p.WebappURITemplate) + case TransferProtocol: + return share.NewTransferProtocol(*p.TransferSourceURI, *p.TransferSharedSecret, uint64(*p.TransferSize)) + } + return nil +} diff --git a/pkg/ocm/share/repository/sql/init.sql b/pkg/ocm/share/repository/sql/init.sql new file mode 100644 index 0000000000..ec94701d84 --- /dev/null +++ b/pkg/ocm/share/repository/sql/init.sql @@ -0,0 +1,81 @@ +CREATE TABLE IF NOT EXISTS ocm_shares ( + id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + token VARCHAR(255) NOT NULL UNIQUE, + fileid_prefix VARCHAR(64) NOT NULL, + item_source VARCHAR(64) NOT NULL, + name TEXT NOT NULL, + share_with VARCHAR(255) NOT NULL, + owner VARCHAR(255) NOT NULL, + initiator TEXT NOT NULL, + ctime INTEGER NOT NULL, + mtime INTEGER NOT NULL, + expiration INTEGER DEFAULT NULL, + type TINYINT NOT NULL, + UNIQUE(fileid_prefix, item_source, share_with, owner) +); + +CREATE TABLE IF NOT EXISTS ocm_shares_access_methods ( + id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + ocm_share_id INTEGER NOT NULL, + type TINYINT NOT NULL, + FOREIGN KEY (ocm_share_id) REFERENCES ocm_shares(id) ON DELETE CASCADE, + UNIQUE (ocm_share_id, type) +); + +CREATE TABLE IF NOT EXISTS ocm_access_method_webdav ( + ocm_access_method_id INTEGER NOT NULL PRIMARY KEY, + permissions INTEGER NOT NULL, + FOREIGN KEY (ocm_access_method_id) REFERENCES ocm_shares_access_methods(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS ocm_access_method_webapp ( + ocm_access_method_id INTEGER NOT NULL PRIMARY KEY, + view_mode INTEGER NOT NULL, + FOREIGN KEY (ocm_access_method_id) REFERENCES ocm_shares_access_methods(id) ON DELETE CASCADE +); + + +CREATE TABLE IF NOT EXISTS ocm_received_shares ( + id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(255) NOT NULL, + fileid_prefix VARCHAR(255) NOT NULL, + item_source VARCHAR(255) NOT NULL, + share_with VARCHAR(255) NOT NULL, + owner VARCHAR(255) NOT NULL, + initiator VARCHAR(255) NOT NULL, + ctime INTEGER NOT NULL, + mtime INTEGER NOT NULL, + expiration INTEGER DEFAULT NULL, + type TINYINT NOT NULL, + state TINYINT NOT NULL +); + +CREATE TABLE IF NOT EXISTS ocm_received_share_protocols ( + id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + ocm_received_share_id INTEGER NOT NULL, + type TINYINT NOT NULL, + FOREIGN KEY (ocm_received_share_id) REFERENCES ocm_received_shares(id) ON DELETE CASCADE, + UNIQUE (ocm_received_share_id, type) +); + +CREATE TABLE IF NOT EXISTS ocm_protocol_webdav ( + ocm_protocol_id INTEGER NOT NULL PRIMARY KEY, + uri VARCHAR(255) NOT NULL, + shared_secret VARCHAR(255) NOT NULL, + permissions INTEGER NOT NULL, + FOREIGN KEY (ocm_protocol_id) REFERENCES ocm_received_share_protocols(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS ocm_protocol_webapp ( + ocm_protocol_id INTEGER NOT NULL PRIMARY KEY, + uri_template VARCHAR(255) NOT NULL, + FOREIGN KEY (ocm_protocol_id) REFERENCES ocm_received_share_protocols(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS ocm_protocol_transfer ( + ocm_protocol_id INTEGER NOT NULL PRIMARY KEY, + source_uri VARCHAR(255) NOT NULL, + shared_secret VARCHAR(255) NOT NULL, + size INTEGER NOT NULL, + FOREIGN KEY (ocm_protocol_id) REFERENCES ocm_received_share_protocols(id) ON DELETE CASCADE +); diff --git a/pkg/ocm/share/repository/sql/sql.go b/pkg/ocm/share/repository/sql/sql.go new file mode 100644 index 0000000000..6bf58ddd0e --- /dev/null +++ b/pkg/ocm/share/repository/sql/sql.go @@ -0,0 +1,687 @@ +// Copyright 2018-2023 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package sql + +import ( + "context" + "database/sql" + "fmt" + "strconv" + "strings" + + userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1" + "github.com/cs3org/reva/internal/http/services/owncloud/ocs/conversions" + "github.com/cs3org/reva/pkg/cbox/utils" + "github.com/cs3org/reva/pkg/errtypes" + "github.com/cs3org/reva/pkg/ocm/share" + "github.com/cs3org/reva/pkg/ocm/share/repository/registry" + "github.com/go-sql-driver/mysql" + "github.com/mitchellh/mapstructure" + "github.com/pkg/errors" + "google.golang.org/genproto/protobuf/field_mask" +) + +func init() { + registry.Register("sql", New) +} + +// New creates a Repository with a SQL driver. +func New(c map[string]interface{}) (share.Repository, error) { + conf, err := parseConfig(c) + if err != nil { + return nil, err + } + + db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s", conf.DBUsername, conf.DBPassword, conf.DBAddress, conf.DBName)) + if err != nil { + return nil, errors.Wrap(err, "sql: error opening connection to mysql database") + } + + m := &mgr{ + c: conf, + db: db, + } + return m, nil +} + +type mgr struct { + c *config + db *sql.DB +} + +type config struct { + DBUsername string `mapstructure:"db_username"` + DBPassword string `mapstructure:"db_password"` + DBAddress string `mapstructure:"db_address"` + DBName string `mapstructure:"db_name"` +} + +func parseConfig(conf map[string]interface{}) (*config, error) { + var c config + if err := mapstructure.Decode(conf, &c); err != nil { + return nil, errors.Wrap(err, "error decoding config") + } + return &c, nil +} + +func formatUserID(u *userpb.UserId) string { + return fmt.Sprintf("%s@%s", u.OpaqueId, u.Idp) +} + +func storeWebDAVAccessMethod(tx *sql.Tx, shareID int64, o *ocm.AccessMethod_WebdavOptions) error { + amID, err := storeAccessMethod(tx, shareID, WebDAVAccessMethod) + if err != nil { + return err + } + + query := "INSERT INTO ocm_access_method_webdav SET ocm_access_method_id=?, permissions=?" + params := []any{amID, conversions.RoleFromResourcePermissions(o.WebdavOptions.Permissions).OCSPermissions()} + + _, err = tx.Exec(query, params...) + return err +} + +func storeWebappAccessMethod(tx *sql.Tx, shareID int64, o *ocm.AccessMethod_WebappOptions) error { + amID, err := storeAccessMethod(tx, shareID, WebDAVAccessMethod) + if err != nil { + return err + } + + query := "INSERT INTO ocm_access_method_webapp SET ocm_access_method_id=?, view_mode=?" + params := []any{amID, int(o.WebappOptions.ViewMode)} + + _, err = tx.Exec(query, params...) + return err +} + +func storeTransferAccessMethod(tx *sql.Tx, shareID int64, _ *ocm.AccessMethod_TransferOptions) error { + _, err := storeAccessMethod(tx, shareID, TransferAccessMethod) + return err +} + +func storeAccessMethod(tx *sql.Tx, shareID int64, t AccessMethod) (int64, error) { + query := "INSERT INTO ocm_shares_access_method SET ocm_share_id=?, type=?" + params := []any{shareID, int(t)} + + res, err := tx.Exec(query, params...) + if err != nil { + return 0, err + } + return res.LastInsertId() +} + +// StoreShare stores a share. +func (m *mgr) StoreShare(ctx context.Context, s *ocm.Share) (*ocm.Share, error) { + if err := transaction(ctx, m.db, func(tx *sql.Tx) error { + // store the share + query := "INSERT INTO ocm_shares SET token=?,fileid_prefix=?,item_source=?,name=?,share_with=?,owner=?,initiator=?,ctime=?,mtime=?,type=?" + params := []any{s.Token, s.ResourceId.StorageId, s.ResourceId.OpaqueId, s.Name, formatUserID(s.Grantee.GetUserId()), s.Owner.OpaqueId, s.Creator.OpaqueId, s.Ctime.Seconds, s.Mtime.Seconds, convertFromCS3OCMShareType(s.ShareType)} + + if s.Expiration != nil { + query += ",expiration=?" + params = append(params, s.Expiration.Seconds) + } + + res, err := tx.Exec(query, params...) + if err != nil { + return err + } + + id, err := res.LastInsertId() + if err != nil { + return err + } + + // store the access methods of the share + for _, m := range s.AccessMethods { + switch r := m.Term.(type) { + case *ocm.AccessMethod_WebdavOptions: + if err := storeWebDAVAccessMethod(tx, id, r); err != nil { + return err + } + case *ocm.AccessMethod_WebappOptions: + if err := storeWebappAccessMethod(tx, id, r); err != nil { + return err + } + case *ocm.AccessMethod_TransferOptions: + if err := storeTransferAccessMethod(tx, id, r); err != nil { + return err + } + } + } + + s.Id = &ocm.ShareId{OpaqueId: strconv.FormatInt(id, 10)} + return nil + }); err != nil { + // check if the share already exists in the db + // https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html#error_er_dup_unique + // https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html#error_er_dup_entry + var e *mysql.MySQLError + if errors.As(err, &e) && (e.Number == 1169 || e.Number == 1062) { + return nil, share.ErrShareAlreadyExisting + } + return nil, err + } + return s, nil +} + +// this func will run f in a transaction, committing if no errors +// rolling back if there were error running f. +func transaction(ctx context.Context, db *sql.DB, f func(*sql.Tx) error) error { + tx, err := db.BeginTx(ctx, nil) + if err != nil { + return err + } + + var txErr error + defer func() { + if txErr == nil { + _ = tx.Commit() + } else { + _ = tx.Rollback() + } + }() + + txErr = f(tx) + return txErr +} + +// GetShare gets the information for a share by the given ref. +func (m *mgr) GetShare(ctx context.Context, user *userpb.User, ref *ocm.ShareReference) (*ocm.Share, error) { + var ( + s *ocm.Share + err error + ) + switch { + case ref.GetId() != nil: + s, err = m.getByID(ctx, user, ref.GetId()) + case ref.GetKey() != nil: + s, err = m.getByKey(ctx, user, ref.GetKey()) + default: + err = errtypes.NotFound(ref.String()) + } + + return s, err +} + +func (m *mgr) getByID(ctx context.Context, user *userpb.User, id *ocm.ShareId) (*ocm.Share, error) { + query := "SELECT id, token, fileid_prefix, item_source, name, share_with, owner, initiator, ctime, mtime, expiration, type FROM ocm_shares WHERE id=? AND (initiator=? OR owner=?)" + + var s dbShare + if err := m.db.QueryRowContext(ctx, query, id.OpaqueId, user.Id.OpaqueId, user.Id.OpaqueId).Scan(&s.ID, &s.Token, &s.Prefix, &s.ItemSource, &s.Name, &s.ShareWith, &s.Owner, &s.Initiator, &s.Ctime, &s.Mtime, &s.Expiration, &s.ShareType); err != nil { + if err == sql.ErrNoRows { + return nil, share.ErrShareNotFound + } + return nil, err + } + + am, err := m.getAccessMethods(ctx, s.ID) + if err != nil { + return nil, err + } + + return convertToCS3OCMShare(&s, am), nil +} + +func (m *mgr) getByKey(ctx context.Context, user *userpb.User, key *ocm.ShareKey) (*ocm.Share, error) { + query := "SELECT id, token, fileid_prefix, item_source, name, share_with, owner, initiator, ctime, mtime, expiration, type FROM ocm_shares WHERE owner=? AND fileid_prefix=? AND item_source=? AND share_with=? AND (initiator=? OR owner=?)" + + var s dbShare + if err := m.db.QueryRowContext(ctx, query, key.Owner.OpaqueId, key.ResourceId.StorageId, key.ResourceId.OpaqueId, formatUserID(key.Grantee.GetUserId()), user.Id.OpaqueId, user.Id.OpaqueId).Scan(&s.ID, &s.Token, &s.Prefix, &s.ItemSource, &s.Name, &s.ShareWith, &s.Owner, &s.Initiator, &s.Ctime, &s.Mtime, &s.Expiration, &s.ShareType); err != nil { + if err == sql.ErrNoRows { + return nil, share.ErrShareNotFound + } + } + + am, err := m.getAccessMethods(ctx, s.ID) + if err != nil { + return nil, err + } + + return convertToCS3OCMShare(&s, am), nil +} + +func (m *mgr) getAccessMethods(ctx context.Context, id int) ([]*ocm.AccessMethod, error) { + query := "SELECT m.type, dav.permissions, app.view_mode FROM ocm_shares_access_method as m LEFT JOIN ocm_access_method_webdav as dav ON m.id=dav.ocm_access_method_id LEFT JOIN ocm_access_method_webapp as app ON m.id=app.ocm_access_method_id WHERE m.ocm_share_id=?" + + var methods []*ocm.AccessMethod + rows, err := m.db.QueryContext(ctx, query, id) + if err != nil { + return nil, err + } + + var a dbAccessMethod + for rows.Next() { + if err := rows.Scan(&a.Type, &a.WebDAVPermissions, &a.WebAppViewMode); err != nil { + continue + } + methods = append(methods, convertToCS3AccessMethod(&a)) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return methods, nil +} + +// DeleteShare deletes the share pointed by ref. +func (m *mgr) DeleteShare(ctx context.Context, user *userpb.User, ref *ocm.ShareReference) error { + switch { + case ref.GetId() != nil: + return m.deleteByID(ctx, user, ref.GetId()) + case ref.GetKey() != nil: + return m.deleteByKey(ctx, user, ref.GetKey()) + default: + return errtypes.NotFound(ref.String()) + } +} + +func (m *mgr) deleteByID(ctx context.Context, user *userpb.User, id *ocm.ShareId) error { + query := "DELETE FROM ocm_shares WHERE id=? AND (owner=? OR initiator=?)" + _, err := m.db.ExecContext(ctx, query, id.OpaqueId, user.Id.OpaqueId, user.Id.OpaqueId) + return err +} + +func (m *mgr) deleteByKey(ctx context.Context, user *userpb.User, key *ocm.ShareKey) error { + query := "DELETE FROM ocm_shares WHERE owner=? AND fileid_prefix=? AND item_source=? AND share_with=? AND (initiator=? OR owner=?)" + _, err := m.db.ExecContext(ctx, query, key.Owner.OpaqueId, key.ResourceId.StorageId, key.ResourceId.OpaqueId, formatUserID(key.Grantee.GetUserId()), user.Id.OpaqueId, user.Id.OpaqueId) + return err +} + +// UpdateShare updates the mode of the given share. +func (m *mgr) UpdateShare(ctx context.Context, user *userpb.User, ref *ocm.ShareReference, p *ocm.SharePermissions) (*ocm.Share, error) { + return nil, errtypes.NotSupported("not yet implemented") +} + +func translateFilters(filters []*ocm.ListOCMSharesRequest_Filter) (string, []any, error) { + var ( + filterQuery strings.Builder + params []any + ) + + grouped := groupFiltersByType(filters) + + var count int + for _, lst := range grouped { + for n, f := range lst { + switch filter := f.Term.(type) { + case *ocm.ListOCMSharesRequest_Filter_ResourceId: + filterQuery.WriteString("fileid_prefix=? AND item_source=?") + params = append(params, filter.ResourceId.StorageId, filter.ResourceId.OpaqueId) + case *ocm.ListOCMSharesRequest_Filter_Creator: + filterQuery.WriteString("initiator=?") + params = append(params, filter.Creator.OpaqueId) + case *ocm.ListOCMSharesRequest_Filter_Owner: + filterQuery.WriteString("owner=?") + params = append(params, filter.Owner.OpaqueId) + default: + return "", nil, errtypes.BadRequest("unknown filter") + } + + if n != len(lst)-1 { + filterQuery.WriteString(" OR ") + } + } + if count != len(grouped)-1 { + filterQuery.WriteString(" AND ") + } + count++ + } + + return filterQuery.String(), params, nil +} + +func groupFiltersByType(filters []*ocm.ListOCMSharesRequest_Filter) map[ocm.ListOCMSharesRequest_Filter_Type][]*ocm.ListOCMSharesRequest_Filter { + m := make(map[ocm.ListOCMSharesRequest_Filter_Type][]*ocm.ListOCMSharesRequest_Filter) + for _, f := range filters { + m[f.Type] = append(m[f.Type], f) + } + return m +} + +// ListShares returns the shares created by the user. If md is provided is not nil, +// it returns only shares attached to the given resource. +func (m *mgr) ListShares(ctx context.Context, user *userpb.User, filters []*ocm.ListOCMSharesRequest_Filter) ([]*ocm.Share, error) { + query := "SELECT id, token, fileid_prefix, item_source, name, share_with, owner, initiator, ctime, mtime, expiration, type FROM ocm_shares WHERE (initiator=? OR owner=?)" + params := []any{user.Id.OpaqueId, user.Id.OpaqueId} + + filterQuery, filterParams, err := translateFilters(filters) + if err != nil { + return nil, err + } + + if filterQuery != "" { + query = fmt.Sprintf("%s AND (%s)", query, filterQuery) + params = append(params, filterParams...) + } + + rows, err := m.db.QueryContext(ctx, query, params...) + if err != nil { + return nil, err + } + + var s dbShare + shares := []*ocm.Share{} + var ids []any + for rows.Next() { + if err := rows.Scan(&s.ID, &s.Token, &s.Prefix, &s.ItemSource, &s.Name, &s.ShareWith, &s.Owner, &s.Initiator, &s.Ctime, &s.Mtime, &s.Expiration, &s.ShareType); err != nil { + continue + } + shares = append(shares, convertToCS3OCMShare(&s, nil)) + ids = append(ids, s.ID) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + // resolve the access method of all the shares + am, err := m.getAccessMethodsIds(ctx, ids) + if err != nil { + return nil, err + } + + // join the results to get the shares with access methods + for _, share := range shares { + if methods, ok := am[share.Id.OpaqueId]; ok { + share.AccessMethods = methods + } + } + + return shares, nil +} + +func (m *mgr) getAccessMethodsIds(ctx context.Context, ids []any) (map[string][]*ocm.AccessMethod, error) { + methods := make(map[string][]*ocm.AccessMethod) + if len(ids) == 0 { + return methods, nil + } + + query := "SELECT m.ocm_share_id, m.type, dav.permissions, app.view_mode FROM ocm_shares_access_method as m LEFT JOIN ocm_access_method_webdav as dav ON m.id=dav.ocm_access_method_id LEFT JOIN ocm_access_method_webapp as app ON m.id=app.ocm_access_method_id WHERE m.ocm_share_id IN " + in := strings.Repeat("?,", len(ids)) + query += "(" + in[:len(in)-1] + ")" + + rows, err := m.db.QueryContext(ctx, query, ids...) + if err != nil { + return nil, err + } + + var am dbAccessMethod + for rows.Next() { + if err := rows.Scan(&am.ShareID, &am.Type, &am.WebDAVPermissions, &am.WebAppViewMode); err != nil { + continue + } + m := convertToCS3AccessMethod(&am) + methods[am.ShareID] = append(methods[am.ShareID], m) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return methods, nil +} + +func storeWebDAVProtocol(tx *sql.Tx, shareID int64, o *ocm.Protocol_WebdavOptions) error { + pID, err := storeProtocol(tx, shareID, WebDAVProtocol) + if err != nil { + return err + } + + query := "INSERT INTO ocm_protocol_webdav SET ocm_protocol_id=?, uri=?, shared_secret=?, permissions=?" + params := []any{pID, o.WebdavOptions.Uri, o.WebdavOptions.SharedSecret, utils.SharePermToInt(o.WebdavOptions.Permissions.Permissions)} + + _, err = tx.Exec(query, params...) + return err +} + +func storeWebappProtocol(tx *sql.Tx, shareID int64, o *ocm.Protocol_WebappOptions) error { + pID, err := storeProtocol(tx, shareID, WebappProtcol) + if err != nil { + return err + } + + query := "INSERT INTO ocm_protocol_webapp SET ocm_protocol_id=?, uri_template=?" + params := []any{pID, o.WebappOptions.UriTemplate} + + _, err = tx.Exec(query, params...) + return err +} + +func storeTransferProtocol(tx *sql.Tx, shareID int64, o *ocm.Protocol_TransferOptions) error { + pID, err := storeProtocol(tx, shareID, TransferProtocol) + if err != nil { + return err + } + + query := "INSERT INTO ocm_protocol_transfer SET ocm_protocol_id=?, source_uri=?, shared_secret=?, size=?" + params := []any{pID, o.TransferOptions.SourceUri, o.TransferOptions.SharedSecret, o.TransferOptions.Size} + + _, err = tx.Exec(query, params...) + return err +} + +func storeProtocol(tx *sql.Tx, shareID int64, p Protocol) (int64, error) { + query := "INSERT INTO ocm_received_share_protocols SET ocm_received_share_id=?, type=?" + params := []any{shareID, int(p)} + + res, err := tx.Exec(query, params...) + if err != nil { + return 0, err + } + return res.LastInsertId() +} + +// StoreReceivedShare stores a received share. +func (m *mgr) StoreReceivedShare(ctx context.Context, s *ocm.ReceivedShare) (*ocm.ReceivedShare, error) { + if err := transaction(ctx, m.db, func(tx *sql.Tx) error { + query := "INSERT INTO ocm_received_shares SET name=?,fileid_prefix=?,item_source=?,share_with=?,owner=?,initiator=?,ctime=?,mtime=?,type=?,state=?" + params := []any{s.Name, s.ResourceId.StorageId, s.ResourceId.OpaqueId, s.Grantee.GetUserId().OpaqueId, formatUserID(s.Owner), formatUserID(s.Creator), s.Ctime.Seconds, s.Mtime.Seconds, convertFromCS3OCMShareType(s.ShareType), convertFromCS3OCMShareState(s.State)} + + if s.Expiration != nil { + query += ",expiration=?" + params = append(params, s.Expiration.Seconds) + } + + res, err := tx.Exec(query, params...) + if err != nil { + return err + } + + id, err := res.LastInsertId() + if err != nil { + return err + } + + for _, p := range s.Protocols { + switch r := p.Term.(type) { + case *ocm.Protocol_WebdavOptions: + if err := storeWebDAVProtocol(tx, id, r); err != nil { + return err + } + case *ocm.Protocol_WebappOptions: + if err := storeWebappProtocol(tx, id, r); err != nil { + return err + } + case *ocm.Protocol_TransferOptions: + if err := storeTransferProtocol(tx, id, r); err != nil { + return err + } + } + } + + s.Id = &ocm.ShareId{OpaqueId: strconv.FormatInt(id, 10)} + return nil + }); err != nil { + // check if the share already exists in the db + // https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html#error_er_dup_unique + var e *mysql.MySQLError + if errors.As(err, &e) && e.Number == 1169 { + return nil, share.ErrShareAlreadyExisting + } + return nil, err + } + + return s, nil +} + +// ListReceivedShares returns the list of shares the user has access. +func (m *mgr) ListReceivedShares(ctx context.Context, user *userpb.User) ([]*ocm.ReceivedShare, error) { + query := "SELECT id, name, fileid_prefix, item_source, share_with, owner, initiator, ctime, mtime, expiration, type, state FROM ocm_received_shares WHERE share_with=?" + + rows, err := m.db.QueryContext(ctx, query, user.Id.OpaqueId) + if err != nil { + return nil, err + } + + var s dbReceivedShare + shares := []*ocm.ReceivedShare{} + var ids []any + for rows.Next() { + if err := rows.Scan(&s.ID, &s.Name, &s.Prefix, &s.ItemSource, &s.ShareWith, &s.Owner, &s.Initiator, &s.Ctime, &s.Mtime, &s.Expiration, &s.Type, &s.State); err != nil { + continue + } + shares = append(shares, convertToCS3OCMReceivedShare(&s, nil)) + ids = append(ids, s.ID) + } + + // resolve the protocols of all the received shares + p, err := m.getProtocolsIds(ctx, ids) + if err != nil { + return nil, err + } + + // join the result to get the shares with protocols + for _, share := range shares { + if protocols, ok := p[share.Id.OpaqueId]; ok { + share.Protocols = protocols + } + } + + return shares, nil +} + +func (m *mgr) getProtocolsIds(ctx context.Context, ids []any) (map[string][]*ocm.Protocol, error) { + protocols := make(map[string][]*ocm.Protocol) + if len(ids) == 0 { + return protocols, nil + } + query := "SELECT p.ocm_received_share_id, p.type, dav.uri, dav.shared_secret, dav.permissions, app.uri_template, tx.source_uri, tx.shared_secret, tx.size FROM ocm_received_share_protocols as p LEFT JOIN ocm_protocol_webdav as dav ON p.id=dav.ocm_protocol_id LEFT JOIN ocm_protocol_webapp as app ON p.id=app.ocm_protocol_id LEFT JOIN ocm_protocol_transfer as tx ON p.id=tx.ocm_protocol_id WHERE p.ocm_received_share_id IN " + in := strings.Repeat("?,", len(ids)) + query += "(" + in[:len(in)-1] + ")" + + rows, err := m.db.QueryContext(ctx, query, ids...) + if err != nil { + return nil, err + } + + var p dbProtocol + for rows.Next() { + if err := rows.Scan(&p.ShareID, &p.Type, &p.WebDAVURI, &p.WebDAVSharedSecret, &p.WebDavPermissions, &p.WebappURITemplate, &p.TransferSourceURI, &p.TransferSharedSecret, &p.TransferSize); err != nil { + continue + } + protocols[p.ShareID] = append(protocols[p.ShareID], convertToCS3Protocol(&p)) + } + + return protocols, nil +} + +// GetReceivedShare returns the information for a received share the user has access. +func (m *mgr) GetReceivedShare(ctx context.Context, user *userpb.User, ref *ocm.ShareReference) (*ocm.ReceivedShare, error) { + var ( + s *ocm.ReceivedShare + err error + ) + switch { + case ref.GetId() != nil: + s, err = m.getReceivedByID(ctx, user, ref.GetId()) + case ref.GetKey() != nil: + s, err = m.getReceivedByKey(ctx, user, ref.GetKey()) + default: + err = errtypes.NotFound(ref.String()) + } + + return s, err +} + +func (m *mgr) getReceivedByID(ctx context.Context, user *userpb.User, id *ocm.ShareId) (*ocm.ReceivedShare, error) { + query := "SELECT id, name, fileid_prefix, item_source, share_with, owner, initiator, ctime, mtime, expiration, type, state FROM ocm_received_shares WHERE id=? AND share_with=?" + params := []any{id.OpaqueId, user.Id.OpaqueId} + + var s dbReceivedShare + if err := m.db.QueryRowContext(ctx, query, params...).Scan(&s.ID, &s.Name, &s.Prefix, &s.ItemSource, &s.ShareWith, &s.Owner, &s.Initiator, &s.Ctime, &s.Mtime, &s.Expiration, &s.Type, &s.State); err != nil { + if err == sql.ErrNoRows { + return nil, share.ErrShareNotFound + } + return nil, err + } + + p, err := m.getProtocols(ctx, s.ID) + if err != nil { + return nil, err + } + + return convertToCS3OCMReceivedShare(&s, p), nil +} + +func (m *mgr) getReceivedByKey(ctx context.Context, user *userpb.User, key *ocm.ShareKey) (*ocm.ReceivedShare, error) { + query := "SELECT id, name, fileid_prefix, item_source, share_with, owner, initiator, ctime, mtime, expiration, type, state FROM ocm_received_shares WHERE owner=? AND fileid_prefix=? AND item_source=? AND share_with=?" + params := []any{formatUserID(key.Owner), key.ResourceId.StorageId, key.ResourceId.OpaqueId, key.Grantee.GetUserId().OpaqueId} + + var s dbReceivedShare + if err := m.db.QueryRowContext(ctx, query, params...).Scan(&s.ID, &s.Name, &s.Prefix, &s.ItemSource, &s.ShareWith, &s.Owner, &s.Initiator, &s.Ctime, &s.Mtime, &s.Expiration, &s.Type, &s.State); err != nil { + if err == sql.ErrNoRows { + return nil, share.ErrShareNotFound + } + return nil, err + } + + p, err := m.getProtocols(ctx, s.ID) + if err != nil { + return nil, err + } + + return convertToCS3OCMReceivedShare(&s, p), nil +} + +func (m *mgr) getProtocols(ctx context.Context, id int) ([]*ocm.Protocol, error) { + query := "SELECT p.type, dav.uri, dav.shared_secret, dav.permissions, app.uri_template, tx.source_uri, tx.shared_secret, tx.size FROM ocm_received_share_protocols as p LEFT JOIN ocm_protocol_webdav as dav ON p.id=dav.ocm_protocol_id LEFT JOIN ocm_protocol_webapp as app ON p.id=app.ocm_protocol_id LEFT JOIN ocm_protocol_transfer as tx ON p.id=tx.ocm_protocol_id WHERE p.ocm_received_share_id=?" + + var protocols []*ocm.Protocol + rows, err := m.db.QueryContext(ctx, query, id) + if err != nil { + return nil, err + } + + var p dbProtocol + for rows.Next() { + if err := rows.Scan(&p.Type, &p.WebDAVURI, &p.WebDAVSharedSecret, &p.WebDavPermissions, &p.WebappURITemplate, &p.TransferSourceURI, &p.TransferSharedSecret, &p.TransferSize); err != nil { + continue + } + protocols = append(protocols, convertToCS3Protocol(&p)) + } + return protocols, nil +} + +// UpdateReceivedShare updates the received share with share state. +func (m *mgr) UpdateReceivedShare(ctx context.Context, user *userpb.User, share *ocm.ReceivedShare, fieldMask *field_mask.FieldMask) (*ocm.ReceivedShare, error) { + return nil, errtypes.NotSupported("not yet implemented") +} diff --git a/pkg/ocm/share/repository/sql/sql_test.go b/pkg/ocm/share/repository/sql/sql_test.go new file mode 100644 index 0000000000..379b379379 --- /dev/null +++ b/pkg/ocm/share/repository/sql/sql_test.go @@ -0,0 +1,1802 @@ +// Copyright 2018-2023 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package sql + +import ( + "context" + "fmt" + "reflect" + "strconv" + "sync" + "testing" + + appprovider "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1" + userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1" + providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" + "github.com/cs3org/reva/internal/http/services/owncloud/ocs/conversions" + + "github.com/cs3org/reva/pkg/ocm/share" + sqle "github.com/dolthub/go-mysql-server" + "github.com/dolthub/go-mysql-server/memory" + "github.com/dolthub/go-mysql-server/server" + "github.com/dolthub/go-mysql-server/sql" + "github.com/gdexlab/go-render/render" +) + +var ( + dbName = "reva_tests" + address = "localhost" + port = 3306 + m sync.Mutex // for increasing the port + ocmShareTable = "ocm_shares" + ocmAccessMethodTable = "ocm_shares_access_method" + ocmAMWebDAVTable = "ocm_access_method_webdav" + ocmAMWebappTable = "ocm_access_method_webapp" + + ocmReceivedShareTable = "ocm_received_shares" + ocmReceivedProtocols = "ocm_received_share_protocols" + ocmProtWebDAVTable = "ocm_protocol_webdav" + ocmProtWebappTable = "ocm_protocol_webapp" + ocmProtTransferTable = "ocm_protocol_transfer" +) + +func startDatabase(ctx *sql.Context, tables map[string]*memory.Table) (engine *sqle.Engine, p int, cleanup func()) { + m.Lock() + defer m.Unlock() + + db := memory.NewDatabase(dbName) + for name, table := range tables { + db.AddTable(name, table) + } + + p = port + config := server.Config{ + Protocol: "tcp", + Address: fmt.Sprintf("%s:%d", address, p), + } + port++ + engine = sqle.NewDefault(memory.NewMemoryDBProvider(db)) + s, err := server.NewDefaultServer(config, engine) + if err != nil { + panic(err) + } + + go func() { + if err := s.Start(); err != nil { + panic(err) + } + }() + cleanup = func() { + if err := s.Close(); err != nil { + panic(err) + } + } + return +} + +func getIDFunc() func() int64 { + var i int64 + return func() int64 { + i++ + return i + } +} + +func createShareTables(ctx *sql.Context, initData []*ocm.Share) map[string]*memory.Table { + id := getIDFunc() + tables := make(map[string]*memory.Table) + + // ocm_shares table + tableShares := memory.NewTable(ocmShareTable, sql.NewPrimaryKeySchema(sql.Schema{ + {Name: "id", Type: sql.Int64, Nullable: false, Source: ocmShareTable, PrimaryKey: true, AutoIncrement: true}, + {Name: "token", Type: sql.Text, Nullable: false, Source: ocmShareTable, PrimaryKey: true}, + {Name: "fileid_prefix", Type: sql.Text, Nullable: false, Source: ocmShareTable}, + {Name: "item_source", Type: sql.Text, Nullable: false, Source: ocmShareTable}, + {Name: "name", Type: sql.Text, Nullable: false, Source: ocmShareTable}, + {Name: "share_with", Type: sql.Text, Nullable: false, Source: ocmShareTable}, + {Name: "owner", Type: sql.Text, Nullable: false, Source: ocmShareTable}, + {Name: "initiator", Type: sql.Text, Nullable: false, Source: ocmShareTable}, + {Name: "ctime", Type: sql.Uint64, Nullable: false, Source: ocmShareTable}, + {Name: "mtime", Type: sql.Uint64, Nullable: false, Source: ocmShareTable}, + {Name: "expiration", Type: sql.Uint64, Nullable: true, Source: ocmShareTable}, + {Name: "type", Type: sql.Int8, Nullable: false, Source: ocmShareTable}, + }), &memory.ForeignKeyCollection{}) + + must(tableShares.CreateIndex(ctx, "test", sql.IndexUsing_BTree, sql.IndexConstraint_Unique, []sql.IndexColumn{ + {Name: "fileid_prefix"}, + {Name: "item_source"}, + {Name: "share_with"}, + {Name: "owner"}, + }, "")) + tables[ocmShareTable] = tableShares + + // ocm_shares_access_method table + var fkAccessMethods memory.ForeignKeyCollection + fkAccessMethods.AddFK(sql.ForeignKeyConstraint{ + Columns: []string{"ocm_share_id"}, + ParentTable: "ocm_shares", + ParentColumns: []string{"id"}, + }) + accessMethods := memory.NewTable(ocmAccessMethodTable, sql.NewPrimaryKeySchema(sql.Schema{ + {Name: "id", Type: sql.Int64, Nullable: false, Source: ocmAccessMethodTable, PrimaryKey: true, AutoIncrement: true}, + {Name: "ocm_share_id", Type: sql.Int64, Nullable: false, Source: ocmAccessMethodTable}, + {Name: "type", Type: sql.Int8, Nullable: false, Source: ocmAccessMethodTable}, + }), &fkAccessMethods) + must(accessMethods.CreateIndex(ctx, "test", sql.IndexUsing_BTree, sql.IndexConstraint_Unique, []sql.IndexColumn{ + {Name: "ocm_share_id"}, + {Name: "type"}, + }, "")) + tables[ocmAccessMethodTable] = accessMethods + + // ocm_access_method_webdav table + var kfProtocols memory.ForeignKeyCollection + kfProtocols.AddFK(sql.ForeignKeyConstraint{ + Columns: []string{"ocm_access_method_id"}, + ParentTable: ocmAccessMethodTable, + ParentColumns: []string{"id"}, + }) + + webdav := memory.NewTable(ocmAMWebDAVTable, sql.NewPrimaryKeySchema(sql.Schema{ + {Name: "ocm_access_method_id", Type: sql.Int64, Nullable: false, Source: ocmAMWebDAVTable}, + {Name: "permissions", Type: sql.Int64, Nullable: false, Source: ocmAMWebDAVTable}, + }), &kfProtocols) + tables[ocmAMWebDAVTable] = webdav + + // ocm_access_method_webapp table + webapp := memory.NewTable(ocmAMWebappTable, sql.NewPrimaryKeySchema(sql.Schema{ + {Name: "ocm_access_method_id", Type: sql.Int64, Nullable: false, Source: ocmAMWebappTable}, + {Name: "view_mode", Type: sql.Int8, Nullable: false, Source: ocmAMWebappTable}, + }), &kfProtocols) + tables[ocmAMWebappTable] = webapp + + for _, share := range initData { + shareWith := share.Grantee.GetUserId() + var expiration uint64 + if share.Expiration != nil { + expiration = share.Expiration.Seconds + } + must(tableShares.Insert(ctx, sql.NewRow(mustInt(share.Id.OpaqueId), share.Token, share.ResourceId.StorageId, share.ResourceId.OpaqueId, share.Name, fmt.Sprintf("%s@%s", shareWith.OpaqueId, shareWith.Idp), share.Owner.OpaqueId, share.Creator.OpaqueId, share.Ctime.Seconds, share.Mtime.Seconds, expiration, int8(ShareTypeUser)))) + + for _, m := range share.AccessMethods { + i := id() + switch am := m.Term.(type) { + case *ocm.AccessMethod_WebdavOptions: + must(accessMethods.Insert(ctx, sql.NewRow(i, mustInt(share.Id.OpaqueId), int8(WebDAVAccessMethod)))) + must(webdav.Insert(ctx, sql.NewRow(i, int64(conversions.RoleFromResourcePermissions(am.WebdavOptions.GetPermissions()).OCSPermissions())))) + case *ocm.AccessMethod_WebappOptions: + must(accessMethods.Insert(ctx, sql.NewRow(i, mustInt(share.Id.OpaqueId), int8(WebappAccessMethod)))) + must(webapp.Insert(ctx, sql.NewRow(i, int8(am.WebappOptions.ViewMode)))) + case *ocm.AccessMethod_TransferOptions: + must(accessMethods.Insert(ctx, sql.NewRow(i, mustInt(share.Id.OpaqueId), int8(TransferAccessMethod)))) + } + } + } + + return tables +} + +func createReceivedShareTables(ctx *sql.Context, initData []*ocm.ReceivedShare) map[string]*memory.Table { + id := getIDFunc() + tables := make(map[string]*memory.Table) + + // ocm_received_shares table + tableShares := memory.NewTable(ocmReceivedShareTable, sql.NewPrimaryKeySchema(sql.Schema{ + {Name: "id", Type: sql.Int64, Nullable: false, Source: ocmReceivedShareTable, PrimaryKey: true, AutoIncrement: true}, + {Name: "name", Type: sql.Text, Nullable: false, Source: ocmReceivedShareTable}, + {Name: "fileid_prefix", Type: sql.Text, Nullable: false, Source: ocmReceivedShareTable}, + {Name: "item_source", Type: sql.Text, Nullable: false, Source: ocmReceivedShareTable}, + {Name: "share_with", Type: sql.Text, Nullable: false, Source: ocmReceivedShareTable}, + {Name: "owner", Type: sql.Text, Nullable: false, Source: ocmReceivedShareTable}, + {Name: "initiator", Type: sql.Text, Nullable: false, Source: ocmReceivedShareTable}, + {Name: "ctime", Type: sql.Uint64, Nullable: false, Source: ocmReceivedShareTable}, + {Name: "mtime", Type: sql.Uint64, Nullable: false, Source: ocmReceivedShareTable}, + {Name: "expiration", Type: sql.Uint64, Nullable: true, Source: ocmReceivedShareTable}, + {Name: "type", Type: sql.Int8, Nullable: false, Source: ocmReceivedShareTable}, + {Name: "state", Type: sql.Int8, Nullable: false, Source: ocmReceivedShareTable}, + }), &memory.ForeignKeyCollection{}) + tables[ocmReceivedShareTable] = tableShares + + // ocm_received_share_protocols table + var fkAccessMethods memory.ForeignKeyCollection + fkAccessMethods.AddFK(sql.ForeignKeyConstraint{ + Columns: []string{"ocm_received_share_id"}, + ParentTable: "ocm_received_shares", + ParentColumns: []string{"id"}, + }) + protocols := memory.NewTable(ocmReceivedProtocols, sql.NewPrimaryKeySchema(sql.Schema{ + {Name: "id", Type: sql.Int64, Nullable: false, Source: ocmReceivedProtocols, PrimaryKey: true, AutoIncrement: true}, + {Name: "ocm_received_share_id", Type: sql.Int64, Nullable: false, Source: ocmReceivedProtocols}, + {Name: "type", Type: sql.Int8, Nullable: false, Source: ocmReceivedProtocols}, + }), &fkAccessMethods) + tables[ocmReceivedProtocols] = protocols + + // ocm_protocol_webdav table + var kfProtocols memory.ForeignKeyCollection + kfProtocols.AddFK(sql.ForeignKeyConstraint{ + Columns: []string{"ocm_protocol_id"}, + ParentTable: ocmReceivedProtocols, + ParentColumns: []string{"id"}, + }) + webdav := memory.NewTable(ocmProtWebDAVTable, sql.NewPrimaryKeySchema(sql.Schema{ + {Name: "ocm_protocol_id", Type: sql.Int64, Source: ocmProtWebDAVTable, PrimaryKey: true, AutoIncrement: true}, + {Name: "uri", Type: sql.Text, Source: ocmProtWebDAVTable, Nullable: false}, + {Name: "shared_secret", Type: sql.Text, Source: ocmProtWebDAVTable, Nullable: false}, + {Name: "permissions", Type: sql.Int64, Source: ocmProtWebDAVTable, Nullable: false}, + }), &kfProtocols) + tables[ocmProtWebDAVTable] = webdav + + // ocm_protocol_webapp table + webapp := memory.NewTable(ocmProtWebappTable, sql.NewPrimaryKeySchema(sql.Schema{ + {Name: "ocm_protocol_id", Type: sql.Int64, Source: ocmProtWebappTable, PrimaryKey: true, AutoIncrement: true}, + {Name: "uri_template", Type: sql.Text, Source: ocmProtWebappTable, Nullable: false}, + }), &kfProtocols) + tables[ocmProtWebappTable] = webapp + + // ocm_protocol_webapp table + transfer := memory.NewTable(ocmProtTransferTable, sql.NewPrimaryKeySchema(sql.Schema{ + {Name: "ocm_protocol_id", Type: sql.Int64, Source: ocmProtTransferTable, PrimaryKey: true, AutoIncrement: true}, + {Name: "source_uri", Type: sql.Text, Source: ocmProtTransferTable, Nullable: false}, + {Name: "shared_secret", Type: sql.Text, Source: ocmProtTransferTable, Nullable: false}, + {Name: "size", Type: sql.Int64, Source: ocmProtTransferTable, Nullable: false}, + }), &kfProtocols) + tables[ocmProtTransferTable] = transfer + + // init data + for _, share := range initData { + var expiration uint64 + if share.Expiration != nil { + expiration = share.Expiration.Seconds + } + + must(tableShares.Insert(ctx, sql.NewRow(mustInt(share.Id.OpaqueId), share.Name, share.ResourceId.StorageId, share.ResourceId.OpaqueId, share.Grantee.GetUserId().OpaqueId, fmt.Sprintf("%s@%s", share.Owner.OpaqueId, share.Owner.Idp), fmt.Sprintf("%s@%s", share.Creator.OpaqueId, share.Creator.Idp), share.Ctime.Seconds, share.Mtime.Seconds, expiration, int8(convertFromCS3OCMShareType(share.ShareType)), int8(convertFromCS3OCMShareState(share.State))))) + + for _, p := range share.Protocols { + i := id() + switch prot := p.Term.(type) { + case *ocm.Protocol_WebdavOptions: + must(protocols.Insert(ctx, sql.NewRow(i, mustInt(share.Id.OpaqueId), int8(WebDAVProtocol)))) + must(webdav.Insert(ctx, sql.NewRow(i, prot.WebdavOptions.Uri, prot.WebdavOptions.SharedSecret, int64(conversions.RoleFromResourcePermissions(prot.WebdavOptions.Permissions.Permissions).OCSPermissions())))) + case *ocm.Protocol_WebappOptions: + must(protocols.Insert(ctx, sql.NewRow(i, mustInt(share.Id.OpaqueId), int8(WebappProtcol)))) + must(webapp.Insert(ctx, sql.NewRow(i, prot.WebappOptions.UriTemplate))) + case *ocm.Protocol_TransferOptions: + must(protocols.Insert(ctx, sql.NewRow(i, mustInt(share.Id.OpaqueId), int8(TransferProtocol)))) + must(transfer.Insert(ctx, sql.NewRow(i, prot.TransferOptions.SourceUri, prot.TransferOptions.SharedSecret, int64(prot.TransferOptions.Size)))) + } + } + } + + return tables +} + +func must(err error) { + if err != nil { + panic(err) + } +} + +func mustInt(s string) int64 { + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + panic(err) + } + return i +} + +func TestGetShare(t *testing.T) { + tests := []struct { + description string + shares []*ocm.Share + query *ocm.ShareReference + user *userpb.User + expected *ocm.Share + err error + }{ + { + description: "empty list", + shares: []*ocm.Share{}, + query: &ocm.ShareReference{Spec: &ocm.ShareReference_Id{Id: &ocm.ShareId{OpaqueId: "non-existing-id"}}}, + user: &userpb.User{Id: &userpb.UserId{OpaqueId: "opaque", Idp: "idp"}}, + expected: nil, + err: share.ErrShareNotFound, + }, + { + description: "query by id", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions())}, + }, + }, + query: &ocm.ShareReference{Spec: &ocm.ShareReference_Id{Id: &ocm.ShareId{OpaqueId: "1"}}}, + user: &userpb.User{Id: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}}, + expected: &ocm.Share{ + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "einstein"}, + Creator: &userpb.UserId{OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions())}, + }, + }, + { + description: "query by key", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions())}, + }, + }, + query: &ocm.ShareReference{ + Spec: &ocm.ShareReference_Key{ + Key: &ocm.ShareKey{ + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + }, + }, + }, + user: &userpb.User{Id: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}}, + expected: &ocm.Share{ + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "einstein"}, + Creator: &userpb.UserId{OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions())}, + }, + }, + { + description: "query by key - not found", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions())}, + }, + }, + query: &ocm.ShareReference{ + Spec: &ocm.ShareReference_Key{ + Key: &ocm.ShareKey{ + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + }, + }, + }, + user: &userpb.User{Id: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}}, + err: share.ErrShareNotFound, + }, + { + description: "query by id - different user", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions())}, + }, + }, + query: &ocm.ShareReference{ + Spec: &ocm.ShareReference_Key{ + Key: &ocm.ShareKey{ + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "cernbox"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + }, + }, + }, + user: &userpb.User{Id: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}}, + err: share.ErrShareNotFound, + }, + { + description: "all access methods", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_ONLY), + share.NewTransferAccessMethod(), + }, + }, + }, + query: &ocm.ShareReference{Spec: &ocm.ShareReference_Id{Id: &ocm.ShareId{OpaqueId: "1"}}}, + user: &userpb.User{Id: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}}, + expected: &ocm.Share{ + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "einstein"}, + Creator: &userpb.UserId{OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_ONLY), + share.NewTransferAccessMethod(), + }, + }, + }, + { + description: "owner gets the share create from an other user", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_ONLY), + share.NewTransferAccessMethod(), + }, + }, + }, + query: &ocm.ShareReference{Spec: &ocm.ShareReference_Id{Id: &ocm.ShareId{OpaqueId: "1"}}}, + user: &userpb.User{Id: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}}, + expected: &ocm.Share{ + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "marie"}, + Creator: &userpb.UserId{OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_ONLY), + share.NewTransferAccessMethod(), + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + ctx := sql.NewEmptyContext() + tables := createShareTables(ctx, tt.shares) + _, port, cleanup := startDatabase(ctx, tables) + t.Cleanup(cleanup) + + r, err := New(map[string]interface{}{ + "db_username": "root", + "db_password": "", + "db_address": fmt.Sprintf("%s:%d", address, port), + "db_name": dbName, + }) + + if err != nil { + t.Fatalf("not expected error while creating share repository driver: %+v", err) + } + + got, err := r.GetShare(context.TODO(), tt.user, tt.query) + if err != tt.err { + t.Fatalf("not expected error getting share. got=%+v expected=%+v", err, tt.err) + } + + if tt.err == nil { + if !reflect.DeepEqual(got, tt.expected) { + t.Fatalf("shares do not match. got=%+v expected=%+v", render.AsCode(got), render.AsCode(tt.expected)) + } + } + }) + } +} + +func TestListShares(t *testing.T) { + tests := []struct { + description string + shares []*ocm.Share + filters []*ocm.ListOCMSharesRequest_Filter + user *userpb.User + expected []*ocm.Share + }{ + { + description: "empty list", + shares: []*ocm.Share{}, + filters: nil, + user: &userpb.User{Id: &userpb.UserId{OpaqueId: "opaque", Idp: "idp"}}, + expected: []*ocm.Share{}, + }, + { + description: "share belong to the user", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_ONLY), + share.NewTransferAccessMethod(), + }, + }, + }, + filters: nil, + user: &userpb.User{Id: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}}, + expected: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "einstein"}, + Creator: &userpb.UserId{OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_ONLY), + share.NewTransferAccessMethod(), + }, + }, + }, + }, + { + description: "all shares belong to the user", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_ONLY), + share.NewTransferAccessMethod(), + }, + }, + { + Id: &ocm.ShareId{OpaqueId: "2"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + }, + filters: nil, + user: &userpb.User{Id: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}}, + expected: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "einstein"}, + Creator: &userpb.UserId{OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_ONLY), + share.NewTransferAccessMethod(), + }, + }, + { + Id: &ocm.ShareId{OpaqueId: "2"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "einstein"}, + Creator: &userpb.UserId{OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + }, + }, + { + description: "select share by user", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_ONLY), + share.NewTransferAccessMethod(), + }, + }, + { + Id: &ocm.ShareId{OpaqueId: "2"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + }, + filters: nil, + user: &userpb.User{Id: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}}, + expected: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "2"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "marie"}, + Creator: &userpb.UserId{OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + }, + }, + { + description: "filter by resource id", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id1"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_ONLY), + share.NewTransferAccessMethod(), + }, + }, + { + Id: &ocm.ShareId{OpaqueId: "2"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id2"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + }, + filters: []*ocm.ListOCMSharesRequest_Filter{ + { + Type: ocm.ListOCMSharesRequest_Filter_TYPE_RESOURCE_ID, + Term: &ocm.ListOCMSharesRequest_Filter_ResourceId{ + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id2"}, + }, + }, + }, + user: &userpb.User{Id: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}}, + expected: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "2"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id2"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "marie"}, + Creator: &userpb.UserId{OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + }, + }, + { + description: "filter by resource id - empty result", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id1"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_ONLY), + share.NewTransferAccessMethod(), + }, + }, + { + Id: &ocm.ShareId{OpaqueId: "2"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id2"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + }, + filters: []*ocm.ListOCMSharesRequest_Filter{ + { + Type: ocm.ListOCMSharesRequest_Filter_TYPE_RESOURCE_ID, + Term: &ocm.ListOCMSharesRequest_Filter_ResourceId{ + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id1"}, + }, + }, + }, + user: &userpb.User{Id: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}}, + expected: []*ocm.Share{}, + }, + { + description: "multiple filters", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id1"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_ONLY), + share.NewTransferAccessMethod(), + }, + }, + { + Id: &ocm.ShareId{OpaqueId: "2"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id1"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + { + Id: &ocm.ShareId{OpaqueId: "3"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id2"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + }, + filters: []*ocm.ListOCMSharesRequest_Filter{ + { + Type: ocm.ListOCMSharesRequest_Filter_TYPE_RESOURCE_ID, + Term: &ocm.ListOCMSharesRequest_Filter_ResourceId{ + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id1"}, + }, + }, + { + Type: ocm.ListOCMSharesRequest_Filter_TYPE_OWNER, + Term: &ocm.ListOCMSharesRequest_Filter_Owner{ + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + }, + }, + }, + user: &userpb.User{Id: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}}, + expected: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id1"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "einstein"}, + Creator: &userpb.UserId{OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_ONLY), + share.NewTransferAccessMethod(), + }, + }, + { + Id: &ocm.ShareId{OpaqueId: "2"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id1"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "einstein"}, + Creator: &userpb.UserId{OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + ctx := sql.NewEmptyContext() + tables := createShareTables(ctx, tt.shares) + _, port, cleanup := startDatabase(ctx, tables) + t.Cleanup(cleanup) + + r, err := New(map[string]interface{}{ + "db_username": "root", + "db_password": "", + "db_address": fmt.Sprintf("%s:%d", address, port), + "db_name": dbName, + }) + + if err != nil { + t.Fatalf("not expected error while creating share repository driver: %+v", err) + } + + got, err := r.ListShares(context.TODO(), tt.user, tt.filters) + if err != nil { + t.Fatalf("not expected error while listing shares: %+v", err) + } + + if !reflect.DeepEqual(got, tt.expected) { + t.Fatalf("list of shares do not match. got=%+v expected=%+v", render.AsCode(got), render.AsCode(tt.expected)) + } + }) + } +} + +type storeShareExpected struct { + shares []sql.Row + accessmethods []sql.Row + webdav []sql.Row + webapp []sql.Row +} + +func checkRows(ctx *sql.Context, engine *sqle.Engine, rows []sql.Row, table string, t *testing.T) { + _, _, err := engine.Query(ctx, "USE "+dbName) + if err != nil { + t.Fatalf("got unexpected error: %+v", err) + } + + _, iter, err := engine.Query(ctx, "SELECT * FROM "+table) + if err != nil { + t.Fatalf("got unexpected error: %+v", err) + } + + gotRows := []sql.Row{} + + for { + row, err := iter.Next(ctx) + if err != nil { + break + } + gotRows = append(gotRows, row) + } + + if !reflect.DeepEqual(gotRows, rows) { + t.Fatalf("rows are not equal. got=%+v expected=%+v", render.AsCode(gotRows), render.AsCode(rows)) + } +} + +func checkShares(ctx *sql.Context, engine *sqle.Engine, exp storeShareExpected, t *testing.T) { + checkRows(ctx, engine, exp.shares, ocmShareTable, t) + checkRows(ctx, engine, exp.accessmethods, ocmAccessMethodTable, t) + checkRows(ctx, engine, exp.webdav, ocmAMWebDAVTable, t) + checkRows(ctx, engine, exp.webapp, ocmAMWebappTable, t) +} + +func TestStoreShare(t *testing.T) { + tests := []struct { + description string + shares []*ocm.Share + toStore *ocm.Share + err error + expected storeShareExpected + }{ + { + description: "empty table", + shares: []*ocm.Share{}, + toStore: &ocm.Share{ + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id1"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "einstein"}, + Creator: &userpb.UserId{OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + expected: storeShareExpected{ + shares: []sql.Row{{int64(1), "qwerty", "storage", "resource-id1", "file-name", "richard@cesnet", "einstein", "marie", uint64(1670859468), uint64(1670859468), nil, int8(0)}}, + accessmethods: []sql.Row{{int64(1), int64(1), int8(0)}}, + webdav: []sql.Row{{int64(1), int64(1)}}, + webapp: []sql.Row{}, + }, + }, + { + description: "non empty table", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "10"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id1"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "einstein"}, + Creator: &userpb.UserId{OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + }, + toStore: &ocm.Share{ + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "other-resource"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "einstein"}, + Creator: &userpb.UserId{OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + expected: storeShareExpected{ + shares: []sql.Row{ + {int64(10), "qwerty", "storage", "resource-id1", "file-name", "richard@cesnet", "einstein", "marie", uint64(1670859468), uint64(1670859468), uint64(0), int8(0)}, + {int64(11), "qwerty", "storage", "other-resource", "file-name", "richard@cesnet", "einstein", "marie", uint64(1670859468), uint64(1670859468), nil, int8(0)}, + }, + accessmethods: []sql.Row{ + {int64(1), int64(10), int8(0)}, + {int64(2), int64(11), int8(0)}, + }, + webdav: []sql.Row{ + {int64(1), int64(1)}, + {int64(2), int64(1)}, + }, + webapp: []sql.Row{}, + }, + }, + { + description: "share already exists", + shares: []*ocm.Share{ + { + Id: &ocm.ShareId{OpaqueId: "10"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id1"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "einstein"}, + Creator: &userpb.UserId{OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + }, + toStore: &ocm.Share{ + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "resource-id1"}, + Name: "file-name", + Token: "qwerty", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard", Type: userpb.UserType_USER_TYPE_FEDERATED}}}, + Owner: &userpb.UserId{OpaqueId: "einstein"}, + Creator: &userpb.UserId{OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: []*ocm.AccessMethod{ + share.NewWebDavAccessMethod(conversions.NewViewerRole().CS3ResourcePermissions()), + }, + }, + err: share.ErrShareAlreadyExisting, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + ctx := sql.NewEmptyContext() + tables := createShareTables(ctx, tt.shares) + engine, port, cleanup := startDatabase(ctx, tables) + t.Cleanup(cleanup) + + r, err := New(map[string]interface{}{ + "db_username": "root", + "db_password": "", + "db_address": fmt.Sprintf("%s:%d", address, port), + "db_name": dbName, + }) + + if err != nil { + t.Fatalf("not expected error while creating share repository driver: %+v", err) + } + + _, err = r.StoreShare(context.TODO(), tt.toStore) + if err != tt.err { + t.Fatalf("not expected error getting share. got=%+v expected=%+v", err, tt.err) + } + + if tt.err == nil { + checkShares(ctx, engine, tt.expected, t) + } + }) + } +} + +func TestGetReceivedShare(t *testing.T) { + tests := []struct { + description string + shares []*ocm.ReceivedShare + query *ocm.ShareReference + user *userpb.User + expected *ocm.ReceivedShare + err error + }{ + { + description: "empty list", + shares: []*ocm.ReceivedShare{}, + query: &ocm.ShareReference{Spec: &ocm.ShareReference_Id{Id: &ocm.ShareId{OpaqueId: "non-existing-id"}}}, + user: &userpb.User{Id: &userpb.UserId{OpaqueId: "opaque", Idp: "idp"}}, + expected: nil, + err: share.ErrShareNotFound, + }, + { + description: "query by id", + shares: []*ocm.ReceivedShare{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + }, + }, + }, + query: &ocm.ShareReference{Spec: &ocm.ShareReference_Id{Id: &ocm.ShareId{OpaqueId: "1"}}}, + user: &userpb.User{Id: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}, + expected: &ocm.ReceivedShare{ + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + }, + }, + }, + { + description: "query by key", + shares: []*ocm.ReceivedShare{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + }, + }, + }, + query: &ocm.ShareReference{ + Spec: &ocm.ShareReference_Key{ + Key: &ocm.ShareKey{ + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + }, + }, + }, + user: &userpb.User{Id: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}, + expected: &ocm.ReceivedShare{ + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + }, + }, + }, + { + description: "query by key", + shares: []*ocm.ReceivedShare{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + }, + }, + }, + query: &ocm.ShareReference{ + Spec: &ocm.ShareReference_Key{ + Key: &ocm.ShareKey{ + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + }, + }, + }, + user: &userpb.User{Id: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}, + err: share.ErrShareNotFound, + }, + { + description: "query by id - different user", + shares: []*ocm.ReceivedShare{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + }, + }, + }, + query: &ocm.ShareReference{Spec: &ocm.ShareReference_Id{Id: &ocm.ShareId{OpaqueId: "1"}}}, + user: &userpb.User{Id: &userpb.UserId{Idp: "cesnet", OpaqueId: "cernbox"}}, + err: share.ErrShareNotFound, + }, + { + description: "all protocols", + shares: []*ocm.ReceivedShare{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + share.NewWebappProtocol("https://cernbox.cern.ch/ocm/1234"), + share.NewTransferProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", 10), + }, + }, + }, + query: &ocm.ShareReference{Spec: &ocm.ShareReference_Id{Id: &ocm.ShareId{OpaqueId: "1"}}}, + user: &userpb.User{Id: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}, + expected: &ocm.ReceivedShare{ + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + share.NewWebappProtocol("https://cernbox.cern.ch/ocm/1234"), + share.NewTransferProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", 10), + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + ctx := sql.NewEmptyContext() + tables := createReceivedShareTables(ctx, tt.shares) + _, port, cleanup := startDatabase(ctx, tables) + t.Cleanup(cleanup) + + r, err := New(map[string]interface{}{ + "db_username": "root", + "db_password": "", + "db_address": fmt.Sprintf("%s:%d", address, port), + "db_name": dbName, + }) + + if err != nil { + t.Fatalf("not expected error while creating share repository driver: %+v", err) + } + + got, err := r.GetReceivedShare(context.TODO(), tt.user, tt.query) + if err != tt.err { + t.Fatalf("not expected error getting share. got=%+v expected=%+v", err, tt.err) + } + + if tt.err == nil { + if !reflect.DeepEqual(got, tt.expected) { + t.Fatalf("shares do not match. got=%+v expected=%+v", render.AsCode(got), render.AsCode(tt.expected)) + } + } + }) + } +} + +func TestListReceviedShares(t *testing.T) { + tests := []struct { + description string + shares []*ocm.ReceivedShare + user *userpb.User + expected []*ocm.ReceivedShare + }{ + { + description: "empty list", + shares: []*ocm.ReceivedShare{}, + user: &userpb.User{Id: &userpb.UserId{OpaqueId: "opaque", Idp: "idp"}}, + expected: []*ocm.ReceivedShare{}, + }, + { + description: "share belong to user", + shares: []*ocm.ReceivedShare{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + share.NewWebappProtocol("https://cernbox.cern.ch/ocm/1234"), + share.NewTransferProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", 10), + }, + }, + }, + user: &userpb.User{Id: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}, + expected: []*ocm.ReceivedShare{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + share.NewWebappProtocol("https://cernbox.cern.ch/ocm/1234"), + share.NewTransferProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", 10), + }, + }, + }, + }, + { + description: "all shares belong to user", + shares: []*ocm.ReceivedShare{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + share.NewWebappProtocol("https://cernbox.cern.ch/ocm/1234"), + share.NewTransferProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", 10), + }, + }, + { + Id: &ocm.ShareId{OpaqueId: "2"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "richard"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "richard"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebappProtocol("https://cernbox.cern.ch/ocm/54321"), + }, + }, + }, + user: &userpb.User{Id: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}, + expected: []*ocm.ReceivedShare{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + share.NewWebappProtocol("https://cernbox.cern.ch/ocm/1234"), + share.NewTransferProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", 10), + }, + }, + { + Id: &ocm.ShareId{OpaqueId: "2"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "richard", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "richard", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebappProtocol("https://cernbox.cern.ch/ocm/54321"), + }, + }, + }, + }, + { + description: "select share by user", + shares: []*ocm.ReceivedShare{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + share.NewWebappProtocol("https://cernbox.cern.ch/ocm/1234"), + share.NewTransferProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", 10), + }, + }, + { + Id: &ocm.ShareId{OpaqueId: "2"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "einstein"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "richard"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "richard"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebappProtocol("https://cernbox.cern.ch/ocm/54321"), + }, + }, + }, + user: &userpb.User{Id: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}, + expected: []*ocm.ReceivedShare{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein", Type: userpb.UserType_USER_TYPE_FEDERATED}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + share.NewWebappProtocol("https://cernbox.cern.ch/ocm/1234"), + share.NewTransferProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", 10), + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + ctx := sql.NewEmptyContext() + tables := createReceivedShareTables(ctx, tt.shares) + _, port, cleanup := startDatabase(ctx, tables) + t.Cleanup(cleanup) + + r, err := New(map[string]interface{}{ + "db_username": "root", + "db_password": "", + "db_address": fmt.Sprintf("%s:%d", address, port), + "db_name": dbName, + }) + + if err != nil { + t.Fatalf("not expected error while creating share repository driver: %+v", err) + } + + got, err := r.ListReceivedShares(context.TODO(), tt.user) + if err != nil { + t.Fatalf("not expected error while listing received shares share repository driver: %+v", err) + } + + if !reflect.DeepEqual(got, tt.expected) { + t.Fatalf("shares do not match. got=%+v expected=%+v", render.AsCode(got), render.AsCode(tt.expected)) + } + }) + } +} + +type storeReceivedShareExpected struct { + shares []sql.Row + protocols []sql.Row + webdav []sql.Row + webapp []sql.Row + transfer []sql.Row +} + +func checkReceivedShares(ctx *sql.Context, engine *sqle.Engine, exp storeReceivedShareExpected, t *testing.T) { + checkRows(ctx, engine, exp.shares, ocmReceivedShareTable, t) + checkRows(ctx, engine, exp.protocols, ocmReceivedProtocols, t) + checkRows(ctx, engine, exp.webdav, ocmProtWebDAVTable, t) + checkRows(ctx, engine, exp.webapp, ocmProtWebappTable, t) + checkRows(ctx, engine, exp.transfer, ocmProtTransferTable, t) +} + +func TestStoreReceivedShare(t *testing.T) { + tests := []struct { + description string + shares []*ocm.ReceivedShare + toStore *ocm.ReceivedShare + err error + expected storeReceivedShareExpected + }{ + { + description: "empty table", + shares: []*ocm.ReceivedShare{}, + toStore: &ocm.ReceivedShare{ + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + }, + }, + expected: storeReceivedShareExpected{ + shares: []sql.Row{{int64(1), "file-name", "storage", "opaque-id", "marie", "einstein@cernbox", "einstein@cernbox", uint64(1670859468), uint64(1670859468), nil, int8(ShareTypeUser), int8(ShareStateAccepted)}}, + protocols: []sql.Row{{int64(1), int64(1), int8(0)}}, + webdav: []sql.Row{{int64(1), "webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", int64(15)}}, + webapp: []sql.Row{}, + transfer: []sql.Row{}, + }, + }, + { + description: "non empty table", + shares: []*ocm.ReceivedShare{ + { + Id: &ocm.ShareId{OpaqueId: "1"}, + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "opaque-id"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "marie"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "einstein"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + }, + }, + }, + toStore: &ocm.ReceivedShare{ + ResourceId: &providerv1beta1.ResourceId{StorageId: "storage", OpaqueId: "new-resource"}, + Name: "file-name", + Grantee: &providerv1beta1.Grantee{Type: providerv1beta1.GranteeType_GRANTEE_TYPE_USER, Id: &providerv1beta1.Grantee_UserId{UserId: &userpb.UserId{Idp: "cesnet", OpaqueId: "richard"}}}, + Owner: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + Creator: &userpb.UserId{Idp: "cernbox", OpaqueId: "marie"}, + Ctime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + Mtime: &typesv1beta1.Timestamp{Seconds: 1670859468}, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + State: ocm.ShareState_SHARE_STATE_PENDING, + Protocols: []*ocm.Protocol{ + share.NewWebDAVProtocol("webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + share.NewTransferProtocol("https://transfer.cernbox.cern.ch/ocm/1234", "secret", 100), + share.NewWebappProtocol("https://app.cernbox.cern.ch/ocm/1234"), + }, + }, + expected: storeReceivedShareExpected{ + shares: []sql.Row{ + {int64(1), "file-name", "storage", "opaque-id", "marie", "einstein@cernbox", "einstein@cernbox", uint64(1670859468), uint64(1670859468), uint64(0), int8(ShareTypeUser), int8(ShareStateAccepted)}, + {int64(2), "file-name", "storage", "new-resource", "richard", "marie@cernbox", "marie@cernbox", uint64(1670859468), uint64(1670859468), nil, int8(ShareTypeUser), int8(ShareStatePending)}, + }, + protocols: []sql.Row{ + {int64(1), int64(1), int8(WebDAVProtocol)}, + {int64(2), int64(2), int8(WebDAVProtocol)}, + {int64(3), int64(2), int8(TransferProtocol)}, + {int64(4), int64(2), int8(WebappProtcol)}, + }, + webdav: []sql.Row{ + {int64(1), "webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", int64(15)}, + {int64(2), "webdav+https//cernbox.cern.ch/dav/ocm/1", "secret", int64(15)}, + }, + webapp: []sql.Row{ + {int64(4), "https://app.cernbox.cern.ch/ocm/1234"}, + }, + transfer: []sql.Row{ + {int64(3), "https://transfer.cernbox.cern.ch/ocm/1234", "secret", int64(100)}, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + ctx := sql.NewEmptyContext() + tables := createReceivedShareTables(ctx, tt.shares) + engine, port, cleanup := startDatabase(ctx, tables) + t.Cleanup(cleanup) + + r, err := New(map[string]interface{}{ + "db_username": "root", + "db_password": "", + "db_address": fmt.Sprintf("%s:%d", address, port), + "db_name": dbName, + }) + + if err != nil { + t.Fatalf("not expected error while creating share repository driver: %+v", err) + } + + _, err = r.StoreReceivedShare(context.TODO(), tt.toStore) + if err != tt.err { + t.Fatalf("not expected error getting share. got=%+v expected=%+v", err, tt.err) + } + + if tt.err == nil { + checkReceivedShares(ctx, engine, tt.expected, t) + } + }) + } +}