diff --git a/go.mod b/go.mod
index a36289c5..7d895870 100644
--- a/go.mod
+++ b/go.mod
@@ -8,15 +8,15 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.5.1
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387
- github.com/aws/aws-sdk-go-v2 v1.17.0
- github.com/aws/aws-sdk-go-v2/config v1.17.9
- github.com/aws/aws-sdk-go-v2/credentials v1.12.22
- github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.18
- github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.36
- github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.13.20
- github.com/aws/aws-sdk-go-v2/service/s3 v1.29.0
- github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.3
- github.com/aws/aws-sdk-go-v2/service/sts v1.17.0
+ github.com/aws/aws-sdk-go-v2 v1.17.1
+ github.com/aws/aws-sdk-go-v2/config v1.17.10
+ github.com/aws/aws-sdk-go-v2/credentials v1.12.23
+ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19
+ github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.37
+ github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.13.21
+ github.com/aws/aws-sdk-go-v2/service/s3 v1.29.1
+ github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.4
+ github.com/aws/aws-sdk-go-v2/service/sts v1.17.1
github.com/cockroachdb/cockroach-go/v2 v2.2.16
github.com/coreos/go-oidc/v3 v3.4.0
github.com/eikenb/pipeat v0.0.0-20210730190139-06b3e6902001
@@ -34,12 +34,12 @@ require (
github.com/hashicorp/go-hclog v1.3.1
github.com/hashicorp/go-plugin v1.4.5
github.com/hashicorp/go-retryablehttp v0.7.1
- github.com/jackc/pgx/v5 v5.0.4-0.20221022150232-3e825ec8982f
+ github.com/jackc/pgx/v5 v5.0.4
github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126
- github.com/klauspost/compress v1.15.11
+ github.com/klauspost/compress v1.15.12
github.com/lestrrat-go/jwx v1.2.25
github.com/lithammer/shortuuid/v3 v3.0.7
- github.com/mattn/go-sqlite3 v1.14.15
+ github.com/mattn/go-sqlite3 v1.14.16
github.com/mhale/smtpd v0.8.0
github.com/minio/sio v0.3.0
github.com/otiai10/copy v1.7.0
@@ -54,9 +54,9 @@ require (
github.com/sftpgo/sdk v0.1.2
github.com/shirou/gopsutil/v3 v3.22.9
github.com/spf13/afero v1.9.2
- github.com/spf13/cobra v1.6.0
+ github.com/spf13/cobra v1.6.1
github.com/spf13/viper v1.13.0
- github.com/stretchr/testify v1.8.0
+ github.com/stretchr/testify v1.8.1
github.com/studio-b12/gowebdav v0.0.0-20221015232716-17255f2e7423
github.com/subosito/gotenv v1.4.1
github.com/unrolled/secure v1.13.0
@@ -71,28 +71,29 @@ require (
golang.org/x/oauth2 v0.1.0
golang.org/x/sys v0.1.0
golang.org/x/time v0.1.0
- google.golang.org/api v0.100.0
+ google.golang.org/api v0.101.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0
)
require (
- cloud.google.com/go v0.104.0 // indirect
- cloud.google.com/go/compute v1.10.0 // indirect
- cloud.google.com/go/iam v0.5.0 // indirect
+ cloud.google.com/go v0.105.0 // indirect
+ cloud.google.com/go/compute v1.12.1 // indirect
+ cloud.google.com/go/compute/metadata v0.1.1 // indirect
+ cloud.google.com/go/iam v0.6.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.1 // indirect
github.com/ajg/form v1.5.1 // indirect
- github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.8 // indirect
- github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.24 // indirect
- github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.18 // indirect
- github.com/aws/aws-sdk-go-v2/internal/ini v1.3.25 // indirect
- github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.15 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.19 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.18 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.18 // indirect
- github.com/aws/aws-sdk-go-v2/service/sso v1.11.24 // indirect
- github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.7 // indirect
- github.com/aws/smithy-go v1.13.3 // indirect
+ github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.9 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.19 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/ini v1.3.26 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.16 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.10 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.20 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.19 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sso v1.11.25 // indirect
+ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8 // indirect
+ github.com/aws/smithy-go v1.13.4 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/boombuler/barcode v1.0.1 // indirect
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
@@ -131,7 +132,7 @@ require (
github.com/magiconair/properties v1.8.6 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
- github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect
+ github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/miekg/dns v1.1.50 // indirect
github.com/minio/sha256-simd v1.0.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
@@ -159,7 +160,7 @@ require (
golang.org/x/tools v0.2.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/genproto v0.0.0-20221018160656-63c7b68cfc55 // indirect
+ google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71 // indirect
google.golang.org/grpc v1.50.1 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
@@ -171,5 +172,5 @@ require (
replace (
github.com/jlaffaye/ftp => github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9
golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20221020054403-a265c1cba3cb
- golang.org/x/net => github.com/drakkan/net v0.0.0-20221020052826-79457e688bf9
+ golang.org/x/net => github.com/drakkan/net v0.0.0-20221026175805-eaebd725b308
)
diff --git a/go.sum b/go.sum
index ebee9238..c734580c 100644
--- a/go.sum
+++ b/go.sum
@@ -36,8 +36,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=
cloud.google.com/go v0.103.0/go.mod h1:vwLx1nqLrzLX/fpwSMOXmFIqBOyHsvHbnAdbGSJ+mKk=
-cloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8=
-cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=
+cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y=
+cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@@ -50,16 +50,18 @@ cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6m
cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
-cloud.google.com/go/compute v1.10.0 h1:aoLIYaA1fX3ywihqpBk2APQKOo20nXsp1GEZQbx5Jk4=
-cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU=
+cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0=
+cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU=
+cloud.google.com/go/compute/metadata v0.1.1 h1:/sxEbyrm6cw+XOUw1YxBHlatV71z4vpnmO7z2IZ0h3I=
+cloud.google.com/go/compute/metadata v0.1.1/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY=
cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c=
cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
-cloud.google.com/go/iam v0.5.0 h1:fz9X5zyTWBmamZsqvqZqD7khbifcZF/q+Z1J8pfhIUg=
-cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc=
+cloud.google.com/go/iam v0.6.0 h1:nsqQC88kT5Iwlm4MeNGTpfMWddp6NB/UOLFTH6m1QfQ=
+cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc=
cloud.google.com/go/kms v1.4.0 h1:iElbfoE61VeLhnZcGOltqL8HIly8Nhbe5t6JlH9GXjo=
cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA=
cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4=
@@ -224,70 +226,70 @@ github.com/aws/aws-sdk-go v1.44.45/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4
github.com/aws/aws-sdk-go v1.44.68/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/aws/aws-sdk-go-v2 v1.16.8/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw=
-github.com/aws/aws-sdk-go-v2 v1.17.0 h1:kWm8OZGx0Zvd6PsOfjFtwbw7+uWYp65DK8suo7WVznw=
-github.com/aws/aws-sdk-go-v2 v1.17.0/go.mod h1:SwiyXi/1zTUZ6KIAmLK5V5ll8SiURNUYOqTerZPaF9k=
+github.com/aws/aws-sdk-go-v2 v1.17.1 h1:02c72fDJr87N8RAC2s3Qu0YuvMRZKNZJ9F+lAehCazk=
+github.com/aws/aws-sdk-go-v2 v1.17.1/go.mod h1:JLnGeGONAyi2lWXI1p0PCIOIy333JMVK1U7Hf0aRFLw=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3/go.mod h1:gNsR5CaXKmQSSzrmGxmwmct/r+ZBfbxorAuXYsj/M5Y=
-github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.8 h1:tcFliCWne+zOuUfKNRn8JdFBuWPDuISDH08wD2ULkhk=
-github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.8/go.mod h1:JTnlBSot91steJeti4ryyu/tLd4Sk84O5W22L7O2EQU=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.9 h1:RKci2D7tMwpvGpDNZnGQw9wk6v7o/xSwFcUAuNPoB8k=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.9/go.mod h1:vCmV1q1VK8eoQJ5+aYE7PkK1K6v41qJ5pJdK3ggCDvg=
github.com/aws/aws-sdk-go-v2/config v1.15.15/go.mod h1:A1Lzyy/o21I5/s2FbyX5AevQfSVXpvvIDCoVFD0BC4E=
-github.com/aws/aws-sdk-go-v2/config v1.17.9 h1:PyqFD7DTmOx5gdvjFwZH2Tx0vivy+cJdM3SE3NVoWZc=
-github.com/aws/aws-sdk-go-v2/config v1.17.9/go.mod h1:NGC2Ut1x1Gl+qBdh4uGdqRTDtk6f3qS8VQ45kEoyAvM=
+github.com/aws/aws-sdk-go-v2/config v1.17.10 h1:zBy5QQ/mkvHElM1rygHPAzuH+sl8nsdSaxSWj0+rpdE=
+github.com/aws/aws-sdk-go-v2/config v1.17.10/go.mod h1:/4np+UiJJKpWHN7Q+LZvqXYgyjgeXm5+lLfDI6TPZao=
github.com/aws/aws-sdk-go-v2/credentials v1.12.10/go.mod h1:g5eIM5XRs/OzIIK81QMBl+dAuDyoLN0VYaLP+tBqEOk=
-github.com/aws/aws-sdk-go-v2/credentials v1.12.22 h1:HPig9ugqH7Eyf2aqNVAPOCp3L/N2vlQ/IiaTxwcrH8U=
-github.com/aws/aws-sdk-go-v2/credentials v1.12.22/go.mod h1:XfHZqa+J1j2Am2GHrsWtg24tnkFkKxmWbWWel+W1zp0=
+github.com/aws/aws-sdk-go-v2/credentials v1.12.23 h1:LctvcJMIb8pxvk5hQhChpCu0WlU6oKQmcYb1HA4IZSA=
+github.com/aws/aws-sdk-go-v2/credentials v1.12.23/go.mod h1:0awX9iRr/+UO7OwRQFpV1hNtXxOVuehpjVEzrIAYNcA=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.9/go.mod h1:KDCCm4ONIdHtUloDcFvK2+vshZvx4Zmj7UMDfusuz5s=
-github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.18 h1:63dqlW4EI4nfhmXJOUqP0zIaGEHoRPn1ahLz8hUOWrQ=
-github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.18/go.mod h1:O3tSoDcot3jy62HNmq7ms16dPHQMR6nqQxooj8T53tI=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19 h1:E3PXZSI3F2bzyj6XxUXdTIfvp425HHhwKsFvmzBwHgs=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19/go.mod h1:VihW95zQpeKQWVPGkwT+2+WJNQV8UXFfMTWdU6VErL8=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.21/go.mod h1:iIYPrQ2rYfZiB/iADYlhj9HHZ9TTi6PqKQPAqygohbE=
-github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.36 h1:DYIvpSIM9YTdid6yRZk/w2kJhJJIbFnL/76NfzmfaTs=
-github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.36/go.mod h1:1vzWYwKGRitVzk7xD3y8Ko7lg26qX+Pxwb5uRaOPSlM=
+github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.37 h1:e1VtTBo+cLNjres0wTlMkmwCGGRjDEkkrz3frxxcaCs=
+github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.37/go.mod h1:kdAV1UMnCkyG6tZJUC4mHbPoRjPA3dIK0L8mnsHERiM=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.15/go.mod h1:pWrr2OoHlT7M/Pd2y4HV3gJyPb3qj5qMmnPkKSNPYK4=
-github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.24 h1:WFIoN2kiF95/4z4HNcJ9F9B0xFV0vrPlUOf3+uNIujM=
-github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.24/go.mod h1:ghMzB/j2wRbPx5/4jPYxJdOtCG2ggrtY01j8K7FMBDA=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25 h1:nBO/RFxeq/IS5G9Of+ZrgucRciie2qpLy++3UGZ+q2E=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25/go.mod h1:Zb29PYkf42vVYQY6pvSyJCJcFHlPIiY+YKdPtwnvMkY=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.9/go.mod h1:08tUpeSGN33QKSO7fwxXczNfiwCpbj+GxK6XKwqWVv0=
-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.18 h1:c2RKF0UvfdVI6epHtFjDujlbiK+VeY85dP1i4gmYc5w=
-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.18/go.mod h1:fkQKYK/jUhCL/wNS1tOPrlYhr9vqutjCz4zZC1wBE1s=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.19 h1:oRHDrwCTVT8ZXi4sr9Ld+EXk7N/KGssOr2ygNeojEhw=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.19/go.mod h1:6Q0546uHDp421okhmmGfbxzq2hBqbXFNpi4k+Q1JnQA=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.16/go.mod h1:CYmI+7x03jjJih8kBEEFKRQc40UjUokT0k7GbvrhhTc=
-github.com/aws/aws-sdk-go-v2/internal/ini v1.3.25 h1:q4TXoep+lPTJneYxlIdcBrlGmTrhfNwrfkdBt1+HqzA=
-github.com/aws/aws-sdk-go-v2/internal/ini v1.3.25/go.mod h1:9uX0Ksj6Zmsd3iQIyVkwkPWUqhPF6TxT/t8zYwUiQEU=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.3.26 h1:Mza+vlnZr+fPKFKRq/lKGVvM6B/8ZZmNdEopOwSQLms=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.3.26/go.mod h1:Y2OJ+P+MC1u1VKnavT+PshiEuGPyh/7DqxoDNij4/bg=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.6/go.mod h1:O7Oc4peGZDEKlddivslfYFvAbgzvl/GH3J8j3JIGBXc=
-github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.15 h1:15q0OjFjny5qjCC8nI+4DH+MZFDC2/BtXxONBNnVZR8=
-github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.15/go.mod h1:t7/Pw0mlxveHXyfzEkGjzQ59Xu9xUmzOfxe1S52TJ8Q=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.16 h1:2EXB7dtGwRYIN3XQ9qwIW504DVbKIw3r89xQnonGdsQ=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.16/go.mod h1:XH+3h395e3WVdd6T2Z3mPxuI+x/HVtdqVOREkTiyubs=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3/go.mod h1:gkb2qADY+OHaGLKNTYxMaQNacfeyQpZ4csDTQMeFmcw=
-github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9 h1:Lh1AShsuIJTwMkoxVCAYPJgNG5H+eN6SmoUn8nOZ5wE=
-github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9/go.mod h1:a9j48l6yL5XINLHLcOKInjdvknN+vWqPBxqeIDw7ktw=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.10 h1:dpiPHgmFstgkLG07KaYAewvuptq5kvo52xn7tVSrtrQ=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.10/go.mod h1:9cBNUHI2aW4ho0A5T87O294iPDuuUOSIEDjnd1Lq/z0=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.10/go.mod h1:Qks+dxK3O+Z2deAhNo6cJ8ls1bam3tUGUAcgxQP1c70=
-github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.19 h1:jrV+VRNrUuzcwTZxdZMi1JtKMk71FN1H7VaF8XjGl44=
-github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.19/go.mod h1:HGDDjLf/IyINXk4PcEZSEviZulqnePG76iq9/rC5qqo=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.20 h1:KSvtm1+fPXE0swe9GPjc6msyrdTT0LB/BP8eLugL1FI=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.20/go.mod h1:Mp4XI/CkWGD79AQxZ5lIFlgvC0A+gl+4BmyG1F+SfNc=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.9/go.mod h1:yQowTpvdZkFVuHrLBXmczat4W+WJKg/PafBZnGBLga0=
-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.18 h1:5oiCDEOHnYkk7uTVI8Wv6ftdFfb6YlUUNzkeePVIPjY=
-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.18/go.mod h1:QtCDHDOXunxeihz7iU15e09u9gRIeaa5WeE6FZVnGUo=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19 h1:GE25AWCdNUPh9AOJzI9KIJnja7IwUc1WyUqz/JTyJ/I=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19/go.mod h1:02CP6iuYP+IVnBX5HULVdSAku/85eHB2Y9EsFhrkEwU=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.9/go.mod h1:Rc5+wn2k8gFSi3V1Ch4mhxOzjMh+bYSXVFfVaqowQOY=
-github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.18 h1:sk9Z5ZwZpLGq3q8ZhOsw8bORT2t8raWPsFrq/yMMbZ0=
-github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.18/go.mod h1:O1mfO/JzWKUNujOAqD39r7BXqlvhjh/JiPnQ97tvQMc=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.19 h1:piDBAaWkaxkkVV3xJJbTehXCZRXYs49kvpi/LG6LR2o=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.19/go.mod h1:BmQWRVkLTmyNzYPFAZgon53qKLWBNSvonugD1MrSWUs=
github.com/aws/aws-sdk-go-v2/service/kms v1.18.1/go.mod h1:4PZMUkc9rXHWGVB5J9vKaZy3D7Nai79ORworQ3ASMiM=
-github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.13.20 h1:jOpM3C6a/W4cd31hj3qok1NZKu3pWYLEg5IwUharV+o=
-github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.13.20/go.mod h1:pvYIQ3quYKA9wXvn5oY6Suu4RqjURwN1tERJssL57nQ=
+github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.13.21 h1:LpIut7TpOhp8RuTD72PBj8ksPy3+RelT3LPwGgQ8+Hg=
+github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.13.21/go.mod h1:mRGY+k3s1yt7yQA3AfzJhnr68OCs1xDfQfIABFUk+ek=
github.com/aws/aws-sdk-go-v2/service/s3 v1.27.2/go.mod h1:u+566cosFI+d+motIz3USXEh6sN8Nq4GrNXSg2RXVMo=
-github.com/aws/aws-sdk-go-v2/service/s3 v1.29.0 h1:wmROdhyusq7m7HJgSB9Jm955XU4Kvz0FknIbr1dJTjA=
-github.com/aws/aws-sdk-go-v2/service/s3 v1.29.0/go.mod h1:syhASH3D6eA1PCga49mGfvISJh/E2QYaooSIqir3pIM=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.29.1 h1:/EMdFPW/Ppieh0WUtQf1+qCGNLdsq5UWUyevBQ6vMVc=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.29.1/go.mod h1:/NHbqPRiwxSPVOB2Xr+StDEH+GWV/64WwnUjv4KYzV0=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.14/go.mod h1:xakbH8KMsQQKqzX87uyyzTHshc/0/Df8bsTneTS5pFU=
-github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.3 h1:d5S+OhXne5O3cIo999RARy/N1dgXW2ldWgD53qbEAP4=
-github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.3/go.mod h1:+X/VSQcuvHPWPRlM64HoWUJAPwsD86KpU9Z52lrsodM=
+github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.4 h1:Hx79EGrkKNJya2iz2U5A7nyr7DjOu/TGTRefThfBZ1w=
+github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.4/go.mod h1:k6CPuxyzO247nYEM1baEwHH1kRtosRCvgahAepaaShw=
github.com/aws/aws-sdk-go-v2/service/sns v1.17.10/go.mod h1:uITsRNVMeCB3MkWpXxXw0eDz8pW4TYLzj+eyQtbhSxM=
github.com/aws/aws-sdk-go-v2/service/sqs v1.19.1/go.mod h1:A94o564Gj+Yn+7QO1eLFeI7UVv3riy/YBFOfICVqFvU=
github.com/aws/aws-sdk-go-v2/service/ssm v1.27.6/go.mod h1:fiFzQgj4xNOg4/wqmAiPvzgDMXPD+cUEplX/CYn+0j0=
github.com/aws/aws-sdk-go-v2/service/sso v1.11.13/go.mod h1:d7ptRksDDgvXaUvxyHZ9SYh+iMDymm94JbVcgvSYSzU=
-github.com/aws/aws-sdk-go-v2/service/sso v1.11.24 h1:tNfD0JI7VKcIcEzYeIAXCIr8qnoq6DACg3QRt50ofOY=
-github.com/aws/aws-sdk-go-v2/service/sso v1.11.24/go.mod h1:7ZC+G3rX2IsGKIhiGDFiul7rgZPApvFy3dDJO7wKtno=
-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.7 h1:q2FDE8cl8rTPqgrTT0dF7xzIfGAwLMh2P+nU7F2CqVs=
-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.7/go.mod h1:sPh8yf7vmBOI/L9fqP55uq+T9WVoxnqrHMqyvgYC/gA=
+github.com/aws/aws-sdk-go-v2/service/sso v1.11.25 h1:GFZitO48N/7EsFDt8fMa5iYdmWqkUDDB3Eje6z3kbG0=
+github.com/aws/aws-sdk-go-v2/service/sso v1.11.25/go.mod h1:IARHuzTXmj1C0KS35vboR0FeJ89OkEy1M9mWbK2ifCI=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8 h1:jcw6kKZrtNfBPJkaHrscDOZoe5gvi9wjudnxvozYFJo=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8/go.mod h1:er2JHN+kBY6FcMfcBBKNGCT3CarImmdFzishsqBmSRI=
github.com/aws/aws-sdk-go-v2/service/sts v1.16.10/go.mod h1:cftkHYN6tCDNfkSasAmclSfl4l7cySoay8vz7p/ce0E=
-github.com/aws/aws-sdk-go-v2/service/sts v1.17.0 h1:9S0HcZUxKcU3HdN+M6GgLIvdbg9as5aOoHrvwRsPNYU=
-github.com/aws/aws-sdk-go-v2/service/sts v1.17.0/go.mod h1:9pZN58zQc5a4Dkdnhu/rI1lNBui1vP5B0giGCuUt2b0=
+github.com/aws/aws-sdk-go-v2/service/sts v1.17.1 h1:KRAix/KHvjGODaHAMXnxRk9t0D+4IJVUuS/uwXxngXk=
+github.com/aws/aws-sdk-go-v2/service/sts v1.17.1/go.mod h1:bXcN3koeVYiJcdDU89n3kCYILob7Y34AeLopUbZgLT4=
github.com/aws/smithy-go v1.12.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
-github.com/aws/smithy-go v1.13.3 h1:l7LYxGuzK6/K+NzJ2mC+VvLUbae0sL3bXU//04MkmnA=
-github.com/aws/smithy-go v1.13.3/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
+github.com/aws/smithy-go v1.13.4 h1:/RN2z1txIJWeXeOkzX+Hk/4Uuvv7dWtCjbmVJcrskyk=
+github.com/aws/smithy-go v1.13.4/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -539,8 +541,8 @@ github.com/drakkan/crypto v0.0.0-20221020054403-a265c1cba3cb h1:ex3x8ir969oV6bQ8
github.com/drakkan/crypto v0.0.0-20221020054403-a265c1cba3cb/go.mod h1:IBSs4ri4rdTqz2QKcpTKpwKMdM+WJ7atZeL9lCu2swQ=
github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9 h1:LPH1dEblAOO/LoG7yHPMtBLXhQmjaga91/DDjWk9jWA=
github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9/go.mod h1:2lmrmq866uF2tnje75wQHzmPXhmSWUt7Gyx2vgK1RCU=
-github.com/drakkan/net v0.0.0-20221020052826-79457e688bf9 h1:vU78OwgLgNqWDqhsk9So0XtQrPxgMDs85L+A3YotXIA=
-github.com/drakkan/net v0.0.0-20221020052826-79457e688bf9/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
+github.com/drakkan/net v0.0.0-20221026175805-eaebd725b308 h1:F7OUb3MgSa2SuY5mdmseihGXhVhxv1OCuKHrona2eh0=
+github.com/drakkan/net v0.0.0-20221026175805-eaebd725b308/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
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=
@@ -1013,8 +1015,8 @@ github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQ
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
github.com/jackc/pgx/v4 v4.16.0/go.mod h1:N0A9sFdWzkw/Jy1lwoiB64F2+ugFZi987zRxcPez/wI=
github.com/jackc/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ=
-github.com/jackc/pgx/v5 v5.0.4-0.20221022150232-3e825ec8982f h1:DEdjdZkMfuJ9Y9sELu1idpOg7101O6YlpdnSXlh0Et8=
-github.com/jackc/pgx/v5 v5.0.4-0.20221022150232-3e825ec8982f/go.mod h1:U0ynklHtgg43fue9Ly30w3OCSTDPlXjig9ghrNGaguQ=
+github.com/jackc/pgx/v5 v5.0.4 h1:r5O6y84qHX/z/HZV40JBdx2obsHz7/uRj5b+CcYEdeY=
+github.com/jackc/pgx/v5 v5.0.4/go.mod h1:U0ynklHtgg43fue9Ly30w3OCSTDPlXjig9ghrNGaguQ=
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
@@ -1060,8 +1062,8 @@ github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
-github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
+github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM=
+github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.1.2 h1:XhdX4fqAJUA0yj+kUwMavO0hHrSPAecYdYf1ZmxHvak=
github.com/klauspost/cpuid/v2 v2.1.2/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
@@ -1161,12 +1163,12 @@ github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vq
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
-github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
-github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
+github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
+github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
-github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM=
-github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
+github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
+github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
github.com/mhale/smtpd v0.8.0 h1:5JvdsehCg33PQrZBvFyDMMUDQmvbzVpZgKob7eYBJc0=
github.com/mhale/smtpd v0.8.0/go.mod h1:MQl+y2hwIEQCXtNhe5+55n0GZOjSmeqORDIXbqUL3x4=
@@ -1494,8 +1496,8 @@ github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKv
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
-github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI=
-github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
+github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
+github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
@@ -1519,6 +1521,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -1529,8 +1532,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/studio-b12/gowebdav v0.0.0-20221015232716-17255f2e7423 h1:Wd8WDEEusB5+En4PiRWJp1cP59QLNsQun+mOTW8+s6s=
github.com/studio-b12/gowebdav v0.0.0-20221015232716-17255f2e7423/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
@@ -1783,7 +1787,7 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 h1:cu5kTvlzcw1Q5S9f5ip1/cpiB4nXvw1XYzFPGgzLUOY=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -2104,8 +2108,8 @@ google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6F
google.golang.org/api v0.86.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
google.golang.org/api v0.91.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
-google.golang.org/api v0.100.0 h1:LGUYIrbW9pzYQQ8NWXlaIVkgnfubVBZbMFb9P8TK374=
-google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70=
+google.golang.org/api v0.101.0 h1:lJPPeEBIRxGpGLwnBTam1NPEM8Z2BmmXEd3z812pjwM=
+google.golang.org/api v0.101.0/go.mod h1:CjxAAWWt3A3VrUE2IGDY2bgK5qhoG/OkyWVlYcP05MY=
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=
@@ -2216,8 +2220,8 @@ google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljW
google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220802133213-ce4fa296bf78/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc=
-google.golang.org/genproto v0.0.0-20221018160656-63c7b68cfc55 h1:U1u4KB2kx6KR/aJDjQ97hZ15wQs8ZPvDcGcRynBhkvg=
-google.golang.org/genproto v0.0.0-20221018160656-63c7b68cfc55/go.mod h1:45EK0dUbEZ2NHjCeAd2LXmyjAgGUGrpGROgjhC3ADck=
+google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71 h1:GEgb2jF5zxsFJpJfg9RoDDWm7tiwc/DDSTE2BtLUkXU=
+google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
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=
diff --git a/internal/common/connection.go b/internal/common/connection.go
index 15f0a0c1..52824b54 100644
--- a/internal/common/connection.go
+++ b/internal/common/connection.go
@@ -462,7 +462,7 @@ func (c *BaseConnection) RemoveDir(virtualPath string) error {
return c.GetFsError(fs, err)
}
if !fi.IsDir() || fi.Mode()&os.ModeSymlink != 0 {
- c.Log(logger.LevelError, "cannot remove %#v is not a directory", fsPath)
+ c.Log(logger.LevelError, "cannot remove %q is not a directory", fsPath)
return c.GetGenericError(nil)
}
@@ -477,6 +477,132 @@ func (c *BaseConnection) RemoveDir(virtualPath string) error {
return nil
}
+type objectToRemoveMapping struct {
+ fsPath string
+ virtualPath string
+ info os.FileInfo
+}
+
+// orderDirsToRemove orders directories so that the empty ones will be at slice start
+func orderDirsToRemove(fs vfs.Fs, dirsToRemove []objectToRemoveMapping) []objectToRemoveMapping {
+ orderedDirs := make([]objectToRemoveMapping, 0, len(dirsToRemove))
+ removedDirs := make([]string, 0, len(dirsToRemove))
+
+ pathSeparator := "/"
+ if vfs.IsLocalOsFs(fs) {
+ pathSeparator = string(os.PathSeparator)
+ }
+
+ for len(orderedDirs) < len(dirsToRemove) {
+ for idx, d := range dirsToRemove {
+ if util.Contains(removedDirs, d.fsPath) {
+ continue
+ }
+ isEmpty := true
+ for idx1, d1 := range dirsToRemove {
+ if idx == idx1 {
+ continue
+ }
+ if util.Contains(removedDirs, d1.fsPath) {
+ continue
+ }
+ if strings.HasPrefix(d1.fsPath, d.fsPath+pathSeparator) {
+ isEmpty = false
+ break
+ }
+ }
+ if isEmpty {
+ orderedDirs = append(orderedDirs, d)
+ removedDirs = append(removedDirs, d.fsPath)
+ }
+ }
+ }
+
+ return orderedDirs
+}
+
+func (c *BaseConnection) removeDirTree(fs vfs.Fs, fsPath, virtualPath string) error {
+ var dirsToRemove []objectToRemoveMapping
+ var filesToRemove []objectToRemoveMapping
+
+ err := fs.Walk(fsPath, func(walkedPath string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+
+ obj := objectToRemoveMapping{
+ fsPath: walkedPath,
+ virtualPath: fs.GetRelativePath(walkedPath),
+ info: info,
+ }
+ if info.IsDir() {
+ err = c.IsRemoveDirAllowed(fs, obj.fsPath, obj.virtualPath)
+ isDuplicated := false
+ for _, d := range dirsToRemove {
+ if d.fsPath == obj.fsPath {
+ isDuplicated = true
+ break
+ }
+ }
+ if !isDuplicated {
+ dirsToRemove = append(dirsToRemove, obj)
+ }
+ } else {
+ err = c.IsRemoveFileAllowed(obj.virtualPath)
+ filesToRemove = append(filesToRemove, obj)
+ }
+ if err != nil {
+ c.Log(logger.LevelError, "unable to remove dir tree, object %q->%q cannot be removed: %v",
+ virtualPath, fsPath, err)
+ return err
+ }
+
+ return nil
+ })
+ if err != nil {
+ c.Log(logger.LevelError, "failed to remove dir tree %q->%q: error: %+v", virtualPath, fsPath, err)
+ return c.GetFsError(fs, err)
+ }
+
+ for _, fileObj := range filesToRemove {
+ err = c.RemoveFile(fs, fileObj.fsPath, fileObj.virtualPath, fileObj.info)
+ if err != nil {
+ c.Log(logger.LevelError, "unable to remove dir tree, error removing file %q->%q: %v",
+ fileObj.virtualPath, fileObj.fsPath, err)
+ return err
+ }
+ }
+
+ for _, dirObj := range orderDirsToRemove(fs, dirsToRemove) {
+ err = c.RemoveDir(dirObj.virtualPath)
+ if err != nil {
+ c.Log(logger.LevelDebug, "unable to remove dir tree, error removing directory %q->%q: %v",
+ dirObj.virtualPath, dirObj.fsPath, err)
+ return err
+ }
+ }
+
+ return err
+}
+
+// RemoveAll removes the specified path and any children it contains
+func (c *BaseConnection) RemoveAll(virtualPath string) error {
+ fs, fsPath, err := c.GetFsAndResolvedPath(virtualPath)
+ if err != nil {
+ return err
+ }
+
+ fi, err := fs.Lstat(fsPath)
+ if err != nil {
+ c.Log(logger.LevelDebug, "failed to remove path %q: stat error: %+v", fsPath, err)
+ return c.GetFsError(fs, err)
+ }
+ if fi.IsDir() && fi.Mode()&os.ModeSymlink == 0 {
+ return c.removeDirTree(fs, fsPath, virtualPath)
+ }
+ return c.RemoveFile(fs, fsPath, virtualPath, fi)
+}
+
// Rename renames (moves) virtualSourcePath to virtualTargetPath
func (c *BaseConnection) Rename(virtualSourcePath, virtualTargetPath string) error {
if virtualSourcePath == virtualTargetPath {
@@ -509,7 +635,7 @@ func (c *BaseConnection) Rename(virtualSourcePath, virtualTargetPath string) err
initialSize = dstInfo.Size()
}
if !c.User.HasPerm(dataprovider.PermOverwrite, path.Dir(virtualTargetPath)) {
- c.Log(logger.LevelDebug, "renaming %#v -> %#v is not allowed. Target exists but the user %#v"+
+ c.Log(logger.LevelDebug, "renaming %q -> %q is not allowed. Target exists but the user %q"+
"has no overwrite permission", virtualSourcePath, virtualTargetPath, c.User.Username)
return c.GetPermissionDeniedError()
}
@@ -824,11 +950,15 @@ func (c *BaseConnection) checkRecursiveRenameDirPermissions(fsSrc, fsDst vfs.Fs,
if err != nil {
return c.GetFsError(fsSrc, err)
}
+ if walkedPath != sourcePath && vfs.HasImplicitAtomicUploads(fsSrc) {
+ c.Log(logger.LevelInfo, "cannot rename non empty directory %q on this filesystem", virtualSourcePath)
+ return c.GetOpUnsupportedError()
+ }
dstPath := strings.Replace(walkedPath, sourcePath, targetPath, 1)
virtualSrcPath := fsSrc.GetRelativePath(walkedPath)
virtualDstPath := fsDst.GetRelativePath(dstPath)
if !c.isRenamePermitted(fsSrc, fsDst, walkedPath, dstPath, virtualSrcPath, virtualDstPath, info) {
- c.Log(logger.LevelInfo, "rename %#v -> %#v is not allowed, virtual destination path: %#v",
+ c.Log(logger.LevelInfo, "rename %q -> %q is not allowed, virtual destination path: %q",
walkedPath, dstPath, virtualDstPath)
return c.GetPermissionDeniedError()
}
@@ -866,7 +996,7 @@ func (c *BaseConnection) isRenamePermitted(fsSrc, fsDst vfs.Fs, fsSourcePath, fs
virtualTargetPath string, fi os.FileInfo,
) bool {
if !c.isSameResourceRename(virtualSourcePath, virtualTargetPath) {
- c.Log(logger.LevelInfo, "rename %#v->%#v is not allowed: the paths must be on the same resource",
+ c.Log(logger.LevelInfo, "rename %#q->%q is not allowed: the paths must be on the same resource",
virtualSourcePath, virtualTargetPath)
return false
}
diff --git a/internal/common/connection_test.go b/internal/common/connection_test.go
index 77c3fe87..dcfc1dd1 100644
--- a/internal/common/connection_test.go
+++ b/internal/common/connection_test.go
@@ -15,6 +15,7 @@
package common
import (
+ "errors"
"os"
"path"
"path/filepath"
@@ -33,11 +34,17 @@ import (
"github.com/drakkan/sftpgo/v2/internal/vfs"
)
+var (
+ errWalkDir = errors.New("err walk dir")
+ errWalkFile = errors.New("err walk file")
+)
+
// MockOsFs mockable OsFs
type MockOsFs struct {
vfs.Fs
hasVirtualFolders bool
name string
+ err error
}
// Name returns the name for the Fs implementation
@@ -61,11 +68,22 @@ func (fs *MockOsFs) Chtimes(name string, atime, mtime time.Time, isUploading boo
return vfs.ErrVfsUnsupported
}
-func newMockOsFs(hasVirtualFolders bool, connectionID, rootDir, name string) vfs.Fs {
+// Walk returns a duplicate path for testing
+func (fs *MockOsFs) Walk(root string, walkFn filepath.WalkFunc) error {
+ if fs.err == errWalkDir {
+ walkFn("fsdpath", vfs.NewFileInfo("dpath", true, 0, time.Now(), false), nil) //nolint:errcheck
+ return walkFn("fsdpath", vfs.NewFileInfo("dpath", true, 0, time.Now(), false), nil) //nolint:errcheck
+ }
+ walkFn("fsfpath", vfs.NewFileInfo("fpath", false, 0, time.Now(), false), nil) //nolint:errcheck
+ return fs.err
+}
+
+func newMockOsFs(hasVirtualFolders bool, connectionID, rootDir, name string, err error) vfs.Fs {
return &MockOsFs{
Fs: vfs.NewOsFs(connectionID, rootDir, ""),
name: name,
hasVirtualFolders: hasVirtualFolders,
+ err: err,
}
}
@@ -113,7 +131,7 @@ func TestSetStatMode(t *testing.T) {
}
user.Permissions = make(map[string][]string)
user.Permissions["/"] = []string{dataprovider.PermAny}
- fs := newMockOsFs(true, "", user.GetHomeDir(), "")
+ fs := newMockOsFs(true, "", user.GetHomeDir(), "", nil)
conn := NewBaseConnection("", ProtocolWebDAV, "", "", user)
err := conn.handleChmod(fs, fakePath, fakePath, nil)
assert.NoError(t, err)
@@ -148,6 +166,15 @@ func TestRecursiveRenameWalkError(t *testing.T) {
filepath.Join(os.TempDir(), "/target"), "/source", "/target",
vfs.NewFileInfo("source", true, 0, time.Now(), false))
assert.ErrorIs(t, err, os.ErrNotExist)
+
+ fs = newMockOsFs(false, "mockID", filepath.Clean(os.TempDir()), "S3Fs", errWalkDir)
+ err = conn.checkRecursiveRenameDirPermissions(fs, fs, filepath.Join(os.TempDir(), "/source"),
+ filepath.Join(os.TempDir(), "/target"), "/source", "/target",
+ vfs.NewFileInfo("source", true, 0, time.Now(), false))
+ if assert.Error(t, err) {
+ assert.Equal(t, err.Error(), conn.GetOpUnsupportedError().Error())
+ }
+
conn.User.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermUpload,
dataprovider.PermDownload, dataprovider.PermRenameFiles}
// no dir rename permission, the quick check path returns permission error without walking
@@ -441,7 +468,7 @@ func TestMaxWriteSize(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, int64(90), size)
- fs = newMockOsFs(true, fs.ConnectionID(), user.GetHomeDir(), "")
+ fs = newMockOsFs(true, fs.ConnectionID(), user.GetHomeDir(), "", nil)
size, err = conn.GetMaxWriteSize(quotaResult, true, 100, fs.IsUploadResumeSupported())
assert.EqualError(t, err, ErrOpUnsupported.Error())
assert.Equal(t, int64(0), size)
@@ -519,3 +546,98 @@ func TestCheckParentDirsErrors(t *testing.T) {
err = os.RemoveAll(filepath.Join(os.TempDir(), "sub-dir"))
assert.NoError(t, err)
}
+
+func TestRemoveDirTree(t *testing.T) {
+ user := dataprovider.User{
+ BaseUser: sdk.BaseUser{
+ HomeDir: filepath.Clean(os.TempDir()),
+ },
+ }
+ user.Permissions = make(map[string][]string)
+ user.Permissions["/"] = []string{dataprovider.PermAny}
+ fs := vfs.NewOsFs("connID", user.HomeDir, "")
+ connection := NewBaseConnection(fs.ConnectionID(), ProtocolWebDAV, "", "", user)
+
+ vpath := path.Join("adir", "missing")
+ p := filepath.Join(user.HomeDir, "adir", "missing")
+ err := connection.removeDirTree(fs, p, vpath)
+ if assert.Error(t, err) {
+ assert.True(t, fs.IsNotExist(err))
+ }
+
+ fs = newMockOsFs(false, "mockID", user.HomeDir, "", nil)
+ err = connection.removeDirTree(fs, p, vpath)
+ if assert.Error(t, err) {
+ assert.True(t, fs.IsNotExist(err), "unexpected error: %v", err)
+ }
+
+ errFake := errors.New("fake err")
+ fs = newMockOsFs(false, "mockID", user.HomeDir, "", errFake)
+ err = connection.removeDirTree(fs, p, vpath)
+ if assert.Error(t, err) {
+ assert.EqualError(t, err, ErrGenericFailure.Error())
+ }
+
+ fs = newMockOsFs(true, "mockID", user.HomeDir, "", errWalkDir)
+ err = connection.removeDirTree(fs, p, vpath)
+ if assert.Error(t, err) {
+ assert.True(t, fs.IsPermission(err), "unexpected error: %v", err)
+ }
+
+ fs = newMockOsFs(false, "mockID", user.HomeDir, "", errWalkFile)
+ err = connection.removeDirTree(fs, p, vpath)
+ if assert.Error(t, err) {
+ assert.EqualError(t, err, ErrGenericFailure.Error())
+ }
+
+ connection.User.Permissions["/"] = []string{dataprovider.PermListItems}
+ fs = newMockOsFs(false, "mockID", user.HomeDir, "", nil)
+ err = connection.removeDirTree(fs, p, vpath)
+ if assert.Error(t, err) {
+ assert.EqualError(t, err, ErrPermissionDenied.Error())
+ }
+}
+
+func TestOrderDirsToRemove(t *testing.T) {
+ fs := vfs.NewOsFs("id", os.TempDir(), "")
+ dirsToRemove := []objectToRemoveMapping{}
+
+ orderedDirs := orderDirsToRemove(fs, dirsToRemove)
+ assert.Equal(t, len(dirsToRemove), len(orderedDirs))
+
+ dirsToRemove = []objectToRemoveMapping{
+ {
+ fsPath: "dir1",
+ virtualPath: "",
+ },
+ }
+ orderedDirs = orderDirsToRemove(fs, dirsToRemove)
+ assert.Equal(t, len(dirsToRemove), len(orderedDirs))
+
+ dirsToRemove = []objectToRemoveMapping{
+ {
+ fsPath: "dir1",
+ virtualPath: "",
+ },
+ {
+ fsPath: "dir12",
+ virtualPath: "",
+ },
+ {
+ fsPath: filepath.Join("dir1", "a", "b"),
+ virtualPath: "",
+ },
+ {
+ fsPath: filepath.Join("dir1", "a"),
+ virtualPath: "",
+ },
+ }
+
+ orderedDirs = orderDirsToRemove(fs, dirsToRemove)
+ if assert.Equal(t, len(dirsToRemove), len(orderedDirs)) {
+ assert.Equal(t, "dir12", orderedDirs[0].fsPath)
+ assert.Equal(t, filepath.Join("dir1", "a", "b"), orderedDirs[1].fsPath)
+ assert.Equal(t, filepath.Join("dir1", "a"), orderedDirs[2].fsPath)
+ assert.Equal(t, "dir1", orderedDirs[3].fsPath)
+ }
+}
diff --git a/internal/common/protocol_test.go b/internal/common/protocol_test.go
index 129aab4a..5fb18aec 100644
--- a/internal/common/protocol_test.go
+++ b/internal/common/protocol_test.go
@@ -47,6 +47,7 @@ import (
"github.com/sftpgo/sdk"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "github.com/studio-b12/gowebdav"
"golang.org/x/crypto/ssh"
"github.com/drakkan/sftpgo/v2/internal/common"
@@ -61,6 +62,7 @@ import (
"github.com/drakkan/sftpgo/v2/internal/smtp"
"github.com/drakkan/sftpgo/v2/internal/util"
"github.com/drakkan/sftpgo/v2/internal/vfs"
+ "github.com/drakkan/sftpgo/v2/internal/webdavd"
)
const (
@@ -68,6 +70,7 @@ const (
httpProxyAddr = "127.0.0.1:7777"
sftpServerAddr = "127.0.0.1:4022"
smtpServerAddr = "127.0.0.1:2525"
+ webDavServerPort = 9191
defaultUsername = "test_common_sftp"
defaultPassword = "test_password"
defaultSFTPUsername = "test_common_sftpfs_user"
@@ -145,6 +148,13 @@ func TestMain(m *testing.M) {
httpdConf.Bindings[0].Port = 4080
httpdtest.SetBaseURL("http://127.0.0.1:4080")
+ webDavConf := config.GetWebDAVDConfig()
+ webDavConf.Bindings = []webdavd.Binding{
+ {
+ Port: webDavServerPort,
+ },
+ }
+
go func() {
if err := sftpdConf.Initialize(configDir); err != nil {
logger.ErrorToConsole("could not start SFTP server: %v", err)
@@ -159,8 +169,16 @@ func TestMain(m *testing.M) {
}
}()
+ go func() {
+ if err := webDavConf.Initialize(configDir); err != nil {
+ logger.ErrorToConsole("could not start WebDAV server: %v", err)
+ os.Exit(1)
+ }
+ }()
+
waitTCPListening(sftpdConf.Bindings[0].GetAddress())
waitTCPListening(httpdConf.Bindings[0].GetAddress())
+ waitTCPListening(webDavConf.Bindings[0].GetAddress())
go func() {
// start a test HTTP server to receive action notifications
@@ -315,6 +333,50 @@ func TestBaseConnection(t *testing.T) {
assert.NoError(t, err)
}
+func TestRemoveAll(t *testing.T) {
+ u := getTestUser()
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
+ assert.NoError(t, err)
+
+ webDavClient := getWebDavClient(user)
+ err = webDavClient.RemoveAll("/")
+ if assert.Error(t, err) {
+ assert.True(t, gowebdav.IsErrCode(err, http.StatusForbidden))
+ }
+
+ testDir := "baseDir"
+ err = webDavClient.RemoveAll(testDir)
+ assert.NoError(t, err)
+
+ conn, client, err := getSftpClient(user)
+ if assert.NoError(t, err) {
+ defer conn.Close()
+ defer client.Close()
+
+ err = client.Mkdir(testDir)
+ assert.NoError(t, err)
+ err = writeSFTPFile(path.Join(testDir, testFileName), 1234, client)
+ assert.NoError(t, err)
+
+ err = webDavClient.RemoveAll(path.Join(testDir, testFileName))
+ assert.NoError(t, err)
+ _, err = client.Stat(path.Join(testDir, testFileName))
+ assert.Error(t, err)
+
+ err = writeSFTPFile(path.Join(testDir, testFileName), 1234, client)
+ assert.NoError(t, err)
+ err = webDavClient.RemoveAll(testDir)
+ assert.NoError(t, err)
+ _, err = client.Stat(testDir)
+ assert.Error(t, err)
+ }
+
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
+ assert.NoError(t, err)
+ err = os.RemoveAll(user.GetHomeDir())
+ assert.NoError(t, err)
+}
+
func TestRelativeSymlinks(t *testing.T) {
u := getTestUser()
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
@@ -2951,6 +3013,8 @@ func TestResolvePathError(t *testing.T) {
assert.Error(t, err)
_, err = conn.DoStat(testPath, 0, false)
assert.Error(t, err)
+ err = conn.RemoveAll(testPath)
+ assert.Error(t, err)
err = conn.SetStat(testPath, &common.StatAttributes{
Atime: time.Now(),
Mtime: time.Now(),
@@ -6409,6 +6473,17 @@ func getSftpClient(user dataprovider.User) (*ssh.Client, *sftp.Client, error) {
return conn, sftpClient, err
}
+func getWebDavClient(user dataprovider.User) *gowebdav.Client {
+ rootPath := fmt.Sprintf("http://localhost:%d/", webDavServerPort)
+ pwd := defaultPassword
+ if user.Password != "" {
+ pwd = user.Password
+ }
+ client := gowebdav.NewClient(rootPath, user.Username, pwd)
+ client.SetTimeout(10 * time.Second)
+ return client
+}
+
func getTestUser() dataprovider.User {
user := dataprovider.User{
BaseUser: sdk.BaseUser{
diff --git a/internal/common/transfer_test.go b/internal/common/transfer_test.go
index 7e5a4961..b9e71383 100644
--- a/internal/common/transfer_test.go
+++ b/internal/common/transfer_test.go
@@ -62,7 +62,7 @@ func TestTransferUpdateQuota(t *testing.T) {
assert.NoError(t, err)
transfer.ErrTransfer = errFake
- transfer.Fs = newMockOsFs(true, "", "", "S3Fs fake")
+ transfer.Fs = newMockOsFs(true, "", "", "S3Fs fake", nil)
assert.False(t, transfer.updateQuota(1, 0))
}
diff --git a/internal/httpd/api_http_user.go b/internal/httpd/api_http_user.go
index 0901f993..d6faf9ca 100644
--- a/internal/httpd/api_http_user.go
+++ b/internal/httpd/api_http_user.go
@@ -119,12 +119,12 @@ func deleteUserDir(w http.ResponseWriter, r *http.Request) {
defer common.Connections.Remove(connection.GetID())
name := connection.User.GetCleanedPath(r.URL.Query().Get("path"))
- err = connection.RemoveDir(name)
+ err = connection.RemoveAll(name)
if err != nil {
- sendAPIResponse(w, r, err, fmt.Sprintf("Unable to delete directory %#v", name), getMappedStatusCode(err))
+ sendAPIResponse(w, r, err, fmt.Sprintf("Unable to delete directory %q", name), getMappedStatusCode(err))
return
}
- sendAPIResponse(w, r, nil, fmt.Sprintf("Directory %#v deleted", name), http.StatusOK)
+ sendAPIResponse(w, r, nil, fmt.Sprintf("Directory %q deleted", name), http.StatusOK)
}
func getUserFile(w http.ResponseWriter, r *http.Request) {
diff --git a/internal/webdavd/handler.go b/internal/webdavd/handler.go
index 3865cd88..e90852f0 100644
--- a/internal/webdavd/handler.go
+++ b/internal/webdavd/handler.go
@@ -112,21 +112,7 @@ func (c *Connection) RemoveAll(ctx context.Context, name string) error {
c.UpdateLastActivity()
name = util.CleanPath(name)
- fs, p, err := c.GetFsAndResolvedPath(name)
- if err != nil {
- return err
- }
-
- var fi os.FileInfo
- if fi, err = fs.Lstat(p); err != nil {
- c.Log(logger.LevelDebug, "failed to remove file %#v: stat error: %+v", p, err)
- return c.GetFsError(fs, err)
- }
-
- if fi.IsDir() && fi.Mode()&os.ModeSymlink == 0 {
- return c.removeDirTree(fs, p, name)
- }
- return c.RemoveFile(fs, p, name, fi)
+ return c.BaseConnection.RemoveAll(name)
}
// OpenFile opens the named file with specified flag.
@@ -290,111 +276,3 @@ func (c *Connection) handleUploadToExistingFile(fs vfs.Fs, resolvedPath, filePat
return newWebDavFile(baseTransfer, w, nil), nil
}
-
-type objectMapping struct {
- fsPath string
- virtualPath string
- info os.FileInfo
-}
-
-func (c *Connection) removeDirTree(fs vfs.Fs, fsPath, virtualPath string) error {
- var dirsToRemove []objectMapping
- var filesToRemove []objectMapping
-
- err := fs.Walk(fsPath, func(walkedPath string, info os.FileInfo, err error) error {
- if err != nil {
- return err
- }
-
- obj := objectMapping{
- fsPath: walkedPath,
- virtualPath: fs.GetRelativePath(walkedPath),
- info: info,
- }
- if info.IsDir() {
- err = c.IsRemoveDirAllowed(fs, obj.fsPath, obj.virtualPath)
- isDuplicated := false
- for _, d := range dirsToRemove {
- if d.fsPath == obj.fsPath {
- isDuplicated = true
- break
- }
- }
- if !isDuplicated {
- dirsToRemove = append(dirsToRemove, obj)
- }
- } else {
- err = c.IsRemoveFileAllowed(obj.virtualPath)
- filesToRemove = append(filesToRemove, obj)
- }
- if err != nil {
- c.Log(logger.LevelDebug, "unable to remove dir tree, object %#v->%#v cannot be removed: %v",
- virtualPath, fsPath, err)
- return err
- }
-
- return nil
- })
- if err != nil {
- c.Log(logger.LevelError, "failed to remove dir tree %#v->%#v: error: %+v", virtualPath, fsPath, err)
- return err
- }
-
- for _, fileObj := range filesToRemove {
- err = c.RemoveFile(fs, fileObj.fsPath, fileObj.virtualPath, fileObj.info)
- if err != nil {
- c.Log(logger.LevelDebug, "unable to remove dir tree, error removing file %#v->%#v: %v",
- fileObj.virtualPath, fileObj.fsPath, err)
- return err
- }
- }
-
- for _, dirObj := range c.orderDirsToRemove(fs, dirsToRemove) {
- err = c.RemoveDir(dirObj.virtualPath)
- if err != nil {
- c.Log(logger.LevelDebug, "unable to remove dir tree, error removing directory %#v->%#v: %v",
- dirObj.virtualPath, dirObj.fsPath, err)
- return err
- }
- }
-
- return err
-}
-
-// order directories so that the empty ones will be at slice start
-func (c *Connection) orderDirsToRemove(fs vfs.Fs, dirsToRemove []objectMapping) []objectMapping {
- orderedDirs := make([]objectMapping, 0, len(dirsToRemove))
- removedDirs := make([]string, 0, len(dirsToRemove))
-
- pathSeparator := "/"
- if vfs.IsLocalOsFs(fs) {
- pathSeparator = string(os.PathSeparator)
- }
-
- for len(orderedDirs) < len(dirsToRemove) {
- for idx, d := range dirsToRemove {
- if util.Contains(removedDirs, d.fsPath) {
- continue
- }
- isEmpty := true
- for idx1, d1 := range dirsToRemove {
- if idx == idx1 {
- continue
- }
- if util.Contains(removedDirs, d1.fsPath) {
- continue
- }
- if strings.HasPrefix(d1.fsPath, d.fsPath+pathSeparator) {
- isEmpty = false
- break
- }
- }
- if isEmpty {
- orderedDirs = append(orderedDirs, d)
- removedDirs = append(removedDirs, d.fsPath)
- }
- }
- }
-
- return orderedDirs
-}
diff --git a/internal/webdavd/internal_test.go b/internal/webdavd/internal_test.go
index ee479adc..f0e568d9 100644
--- a/internal/webdavd/internal_test.go
+++ b/internal/webdavd/internal_test.go
@@ -19,7 +19,6 @@ import (
"crypto/tls"
"crypto/x509"
"encoding/xml"
- "errors"
"fmt"
"io"
"net/http"
@@ -272,11 +271,6 @@ xr5cb9VBRBtB9aOKVfuRhpatAfS2Pzm2Htae9lFn7slGPUmu2hkjDw==
-----END RSA PRIVATE KEY-----`
)
-var (
- errWalkDir = errors.New("err walk dir")
- errWalkFile = errors.New("err walk file")
-)
-
// MockOsFs mockable OsFs
type MockOsFs struct {
vfs.Fs
@@ -315,86 +309,22 @@ func (fs *MockOsFs) Remove(name string, isDir bool) error {
// Rename renames (moves) source to target
func (fs *MockOsFs) Rename(source, target string) error {
- if fs.err != nil {
- return fs.err
- }
return os.Rename(source, target)
}
-// Walk returns a duplicate path for testing
-func (fs *MockOsFs) Walk(root string, walkFn filepath.WalkFunc) error {
- if fs.err == errWalkDir {
- walkFn("fsdpath", vfs.NewFileInfo("dpath", true, 0, time.Now(), false), nil) //nolint:errcheck
- walkFn("fsdpath", vfs.NewFileInfo("dpath", true, 0, time.Now(), false), nil) //nolint:errcheck
- return nil
- }
- walkFn("fsfpath", vfs.NewFileInfo("fpath", false, 0, time.Now(), false), nil) //nolint:errcheck
- return fs.err
-}
-
// GetMimeType returns the content type
func (fs *MockOsFs) GetMimeType(name string) (string, error) {
return "application/custom-mime", nil
}
-func newMockOsFs(err error, atomicUpload bool, connectionID, rootDir string, reader *pipeat.PipeReaderAt) vfs.Fs {
+func newMockOsFs(atomicUpload bool, connectionID, rootDir string, reader *pipeat.PipeReaderAt) vfs.Fs {
return &MockOsFs{
Fs: vfs.NewOsFs(connectionID, rootDir, ""),
- err: err,
isAtomicUploadSupported: atomicUpload,
reader: reader,
}
}
-func TestOrderDirsToRemove(t *testing.T) {
- user := dataprovider.User{}
- fs := vfs.NewOsFs("id", os.TempDir(), "")
- connection := &Connection{
- BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
- request: nil,
- }
- dirsToRemove := []objectMapping{}
-
- orderedDirs := connection.orderDirsToRemove(fs, dirsToRemove)
- assert.Equal(t, len(dirsToRemove), len(orderedDirs))
-
- dirsToRemove = []objectMapping{
- {
- fsPath: "dir1",
- virtualPath: "",
- },
- }
- orderedDirs = connection.orderDirsToRemove(fs, dirsToRemove)
- assert.Equal(t, len(dirsToRemove), len(orderedDirs))
-
- dirsToRemove = []objectMapping{
- {
- fsPath: "dir1",
- virtualPath: "",
- },
- {
- fsPath: "dir12",
- virtualPath: "",
- },
- {
- fsPath: filepath.Join("dir1", "a", "b"),
- virtualPath: "",
- },
- {
- fsPath: filepath.Join("dir1", "a"),
- virtualPath: "",
- },
- }
-
- orderedDirs = connection.orderDirsToRemove(fs, dirsToRemove)
- if assert.Equal(t, len(dirsToRemove), len(orderedDirs)) {
- assert.Equal(t, "dir12", orderedDirs[0].fsPath)
- assert.Equal(t, filepath.Join("dir1", "a", "b"), orderedDirs[1].fsPath)
- assert.Equal(t, filepath.Join("dir1", "a"), orderedDirs[2].fsPath)
- assert.Equal(t, "dir1", orderedDirs[3].fsPath)
- }
-}
-
func TestUserInvalidParams(t *testing.T) {
u := &dataprovider.User{
BaseUser: sdk.BaseUser{
@@ -643,7 +573,7 @@ func TestFileAccessErrors(t *testing.T) {
assert.ErrorIs(t, err, os.ErrNotExist)
}
- fs = newMockOsFs(nil, false, fs.ConnectionID(), user.HomeDir, nil)
+ fs = newMockOsFs(false, fs.ConnectionID(), user.HomeDir, nil)
_, err = connection.handleUploadToExistingFile(fs, p, p, 0, path.Join("adir", missingPath))
if assert.Error(t, err) {
assert.ErrorIs(t, err, os.ErrNotExist)
@@ -706,59 +636,6 @@ func TestFileAccessErrors(t *testing.T) {
}
}
-func TestRemoveDirTree(t *testing.T) {
- user := dataprovider.User{
- BaseUser: sdk.BaseUser{
- HomeDir: filepath.Clean(os.TempDir()),
- },
- }
- user.Permissions = make(map[string][]string)
- user.Permissions["/"] = []string{dataprovider.PermAny}
- fs := vfs.NewOsFs("connID", user.HomeDir, "")
- connection := &Connection{
- BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
- }
-
- vpath := path.Join("adir", "missing")
- p := filepath.Join(user.HomeDir, "adir", "missing")
- err := connection.removeDirTree(fs, p, vpath)
- if assert.Error(t, err) {
- assert.True(t, fs.IsNotExist(err))
- }
-
- fs = newMockOsFs(nil, false, "mockID", user.HomeDir, nil)
- err = connection.removeDirTree(fs, p, vpath)
- if assert.Error(t, err) {
- assert.True(t, fs.IsNotExist(err), "unexpected error: %v", err)
- }
-
- errFake := errors.New("fake err")
- fs = newMockOsFs(errFake, false, "mockID", user.HomeDir, nil)
- err = connection.removeDirTree(fs, p, vpath)
- if assert.Error(t, err) {
- assert.EqualError(t, err, errFake.Error())
- }
-
- fs = newMockOsFs(errWalkDir, true, "mockID", user.HomeDir, nil)
- err = connection.removeDirTree(fs, p, vpath)
- if assert.Error(t, err) {
- assert.True(t, fs.IsPermission(err), "unexpected error: %v", err)
- }
-
- fs = newMockOsFs(errWalkFile, false, "mockID", user.HomeDir, nil)
- err = connection.removeDirTree(fs, p, vpath)
- if assert.Error(t, err) {
- assert.EqualError(t, err, errWalkFile.Error())
- }
-
- connection.User.Permissions["/"] = []string{dataprovider.PermListItems}
- fs = newMockOsFs(nil, false, "mockID", user.HomeDir, nil)
- err = connection.removeDirTree(fs, p, vpath)
- if assert.Error(t, err) {
- assert.EqualError(t, err, common.ErrPermissionDenied.Error())
- }
-}
-
func TestContentType(t *testing.T) {
user := dataprovider.User{
BaseUser: sdk.BaseUser{
@@ -775,7 +652,7 @@ func TestContentType(t *testing.T) {
ctx := context.Background()
baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
- fs = newMockOsFs(nil, false, fs.ConnectionID(), user.GetHomeDir(), nil)
+ fs = newMockOsFs(false, fs.ConnectionID(), user.GetHomeDir(), nil)
err := os.WriteFile(testFilePath, []byte(""), os.ModePerm)
assert.NoError(t, err)
davFile := newWebDavFile(baseTransfer, nil, nil)
@@ -873,7 +750,7 @@ func TestTransferReadWriteErrors(t *testing.T) {
r, w, err = pipeat.Pipe()
assert.NoError(t, err)
- mockFs := newMockOsFs(nil, false, fs.ConnectionID(), user.HomeDir, r)
+ mockFs := newMockOsFs(false, fs.ConnectionID(), user.HomeDir, r)
baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
common.TransferDownload, 0, 0, 0, 0, false, mockFs, dataprovider.TransferQuota{})
davFile = newWebDavFile(baseTransfer, nil, nil)
@@ -974,13 +851,13 @@ func TestTransferSeek(t *testing.T) {
common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
davFile = newWebDavFile(baseTransfer, nil, nil)
davFile.reader = f
- davFile.Fs = newMockOsFs(nil, true, fs.ConnectionID(), user.GetHomeDir(), nil)
+ davFile.Fs = newMockOsFs(true, fs.ConnectionID(), user.GetHomeDir(), nil)
res, err = davFile.Seek(2, io.SeekStart)
assert.NoError(t, err)
assert.Equal(t, int64(2), res)
davFile = newWebDavFile(baseTransfer, nil, nil)
- davFile.Fs = newMockOsFs(nil, true, fs.ConnectionID(), user.GetHomeDir(), nil)
+ davFile.Fs = newMockOsFs(true, fs.ConnectionID(), user.GetHomeDir(), nil)
res, err = davFile.Seek(2, io.SeekEnd)
assert.NoError(t, err)
assert.Equal(t, int64(5), res)
@@ -989,7 +866,7 @@ func TestTransferSeek(t *testing.T) {
common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
davFile = newWebDavFile(baseTransfer, nil, nil)
- davFile.Fs = newMockOsFs(nil, true, fs.ConnectionID(), user.GetHomeDir(), nil)
+ davFile.Fs = newMockOsFs(true, fs.ConnectionID(), user.GetHomeDir(), nil)
res, err = davFile.Seek(2, io.SeekEnd)
assert.True(t, fs.IsNotExist(err))
assert.Equal(t, int64(0), res)
diff --git a/templates/webclient/files.html b/templates/webclient/files.html
index 0f7835d2..4bb5cef5 100644
--- a/templates/webclient/files.html
+++ b/templates/webclient/files.html
@@ -594,8 +594,10 @@ along with this program. If not, see .
var itemType = getTypeFromMeta(selected);
var itemName = getNameFromMeta(selected);
var path;
+ var reqTimeout = 15000;
if (itemType == "1"){
path = '{{.DirsURL}}';
+ reqTimeout = 90000
} else {
path = '{{.FilesURL}}';
}
@@ -606,7 +608,7 @@ along with this program. If not, see .
type: 'DELETE',
dataType: 'json',
headers: { 'X-CSRF-TOKEN': '{{.CSRFToken}}' },
- timeout: 60000,
+ timeout: reqTimeout,
success: function (result) {
index++;
success++;