From a38ce460bb77f553b2cafdf5785a59c5f1637271 Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Fri, 16 Jun 2023 21:06:21 +0200 Subject: [PATCH] WebClient: show user quota Also remove per-source data transfer limits. This was an oversight Signed-off-by: Nicola Murino --- go.mod | 30 ++-- go.sum | 62 ++++---- internal/common/connection.go | 3 +- internal/common/eventmanager.go | 1 - internal/common/protocol_test.go | 6 - internal/common/transfer_test.go | 41 ++--- internal/common/transferschecker.go | 2 +- internal/common/transferschecker_test.go | 17 +- internal/dataprovider/dataprovider.go | 35 ----- internal/dataprovider/user.go | 30 +--- internal/httpd/httpd_test.go | 164 ------------------- internal/httpd/internal_test.go | 86 ++++++++++ internal/httpd/webadmin.go | 49 ------ internal/httpd/webclient.go | 190 ++++++++++++++++++++++- internal/httpdtest/httpdtest.go | 27 ---- openapi/openapi.yaml | 21 --- templates/webadmin/group.html | 99 ------------ templates/webadmin/sharedcomponents.html | 52 ------- templates/webadmin/user.html | 99 ------------ templates/webclient/files.html | 76 +++++++++ 20 files changed, 409 insertions(+), 681 deletions(-) diff --git a/go.mod b/go.mod index 73aa9f05..1296ef20 100644 --- a/go.mod +++ b/go.mod @@ -10,14 +10,14 @@ require ( github.com/alexedwards/argon2id v0.0.0-20230305115115-4b3c3280a736 github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 github.com/aws/aws-sdk-go-v2 v1.18.1 - github.com/aws/aws-sdk-go-v2/config v1.18.26 - github.com/aws/aws-sdk-go-v2/credentials v1.13.25 + github.com/aws/aws-sdk-go-v2/config v1.18.27 + github.com/aws/aws-sdk-go-v2/credentials v1.13.26 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.68 - github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.14.12 - github.com/aws/aws-sdk-go-v2/service/s3 v1.34.0 - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.19.9 - github.com/aws/aws-sdk-go-v2/service/sts v1.19.1 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.70 + github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.14.13 + github.com/aws/aws-sdk-go-v2/service/s3 v1.35.0 + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.19.10 + github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 github.com/bmatcuk/doublestar/v4 v4.6.0 github.com/cockroachdb/cockroach-go/v2 v2.3.5 github.com/coreos/go-oidc/v3 v3.6.0 @@ -48,12 +48,12 @@ require ( github.com/pires/go-proxyproto v0.7.0 github.com/pkg/sftp v1.13.6-0.20230213180117-971c283182b6 github.com/pquerna/otp v1.4.0 - github.com/prometheus/client_golang v1.15.1 + github.com/prometheus/client_golang v1.16.0 github.com/robfig/cron/v3 v3.0.1 github.com/rs/cors v1.9.0 github.com/rs/xid v1.5.0 github.com/rs/zerolog v1.29.1 - github.com/sftpgo/sdk v0.1.5-0.20230614163902-b9133304e3d2 + github.com/sftpgo/sdk v0.1.5-0.20230616161947-bb4a056935b0 github.com/shirou/gopsutil/v3 v3.23.5 github.com/spf13/afero v1.9.5 github.com/spf13/cobra v1.7.0 @@ -74,7 +74,7 @@ require ( golang.org/x/sys v0.9.0 golang.org/x/term v0.9.0 golang.org/x/time v0.3.0 - google.golang.org/api v0.127.0 + google.golang.org/api v0.128.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 ) @@ -94,8 +94,8 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.29 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.12.11 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.11 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 // indirect github.com/aws/smithy-go v1.13.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/boombuler/barcode v1.0.1 // indirect @@ -145,7 +145,7 @@ require ( github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect + github.com/prometheus/procfs v0.11.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect @@ -158,13 +158,13 @@ require ( go.opencensus.io v0.24.0 // indirect golang.org/x/mod v0.11.0 // indirect golang.org/x/text v0.10.0 // indirect - golang.org/x/tools v0.9.3 // indirect + golang.org/x/tools v0.10.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-20230530153820-e85fd2cbaebc // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect - google.golang.org/grpc v1.55.0 // indirect + google.golang.org/grpc v1.56.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 9e035962..0387d223 100644 --- a/go.sum +++ b/go.sum @@ -564,17 +564,17 @@ github.com/aws/aws-sdk-go-v2 v1.18.1/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3eP github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10/go.mod h1:VeTZetY5KRJLuD/7fkQXMU6Mw7H5m/KP2J5Iy9osMno= github.com/aws/aws-sdk-go-v2/config v1.18.12/go.mod h1:J36fOhj1LQBr+O4hJCiT8FwVvieeoSGOtPuvhKlsNu8= -github.com/aws/aws-sdk-go-v2/config v1.18.26 h1:ivCHcSmKd1+9rBlqVsxZHB35eCW88KWbMdG2VL3BuBw= -github.com/aws/aws-sdk-go-v2/config v1.18.26/go.mod h1:NVmd//z/PNl7U+ZU2EnuffxOA060JWzgbH3BnqQrUoY= +github.com/aws/aws-sdk-go-v2/config v1.18.27 h1:Az9uLwmssTE6OGTpsFqOnaGpLnKDqNYOJzWuC6UAYzA= +github.com/aws/aws-sdk-go-v2/config v1.18.27/go.mod h1:0My+YgmkGxeqjXZb5BYme5pc4drjTnM+x1GJ3zv42Nw= github.com/aws/aws-sdk-go-v2/credentials v1.13.12/go.mod h1:37HG2MBroXK3jXfxVGtbM2J48ra2+Ltu+tmwr/jO0KA= -github.com/aws/aws-sdk-go-v2/credentials v1.13.25 h1:5wROoMcUC7nAE66e0b3IIht6Tos76M4HC+GQw8MeqxU= -github.com/aws/aws-sdk-go-v2/credentials v1.13.25/go.mod h1:W9I2660WXSwZQ23mM1Ks72+UGeyirIxuU7/KzN7daeA= +github.com/aws/aws-sdk-go-v2/credentials v1.13.26 h1:qmU+yhKmOCyujmuPY7tf5MxR/RKyZrOPO3V4DobiTUk= +github.com/aws/aws-sdk-go-v2/credentials v1.13.26/go.mod h1:GoXt2YC8jHUBbA4jr+W3JiemnIbkXOfxSXcisUsZ3os= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.22/go.mod h1:YGSIJyQ6D6FjKMQh16hVFSIUD54L4F7zTGePqYMYYJU= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 h1:LxK/bitrAr4lnh9LnIS6i7zWbCOdMsfzKFBI6LUCS0I= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4/go.mod h1:E1hLXN/BL2e6YizK1zFlYd8vsfi2GTjbjBazinMmeaM= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.51/go.mod h1:7Grl2gV+dx9SWrUIgwwlUvU40t7+lOSbx34XwfmsTkY= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.68 h1:0+IIldXpZPgIO1cvJJc1/83dzVOfeRWvSPUfED3fyfs= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.68/go.mod h1:LIq1+fhV5PgIQ3DhL8D20v4jTQ95wK0FywDFBiype1k= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.70 h1:4bh28MeeXoBFTjb0JjQ5sVatzlf5xA1DziV8mZed9v4= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.70/go.mod h1:9yI5NXzqy2yOiMytv6QLZHvlyHLwYxO9iIq+bZIbrFg= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28/go.mod h1:3lwChorpIM/BhImY/hy+Z6jekmN92cXGPI1QJasVPYY= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34 h1:A5UqQEmPaCFpedKouS4v+dHCTUo2sKqhoKO9U5kxyWo= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34/go.mod h1:wZpTEecJe0Btj3IYnDx/VlUzor9wm3fJHyvLpQF0VwY= @@ -600,26 +600,26 @@ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.22/go.mod h1:QFVbqK github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3 h1:dBL3StFxHtpBzJJ/mNEsjXVgfO+7jR0dAIEwLqMapEA= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3/go.mod h1:f1QyiAsvIv4B49DmCqrhlXqyaR+0IxMmyX+1P+AnzOM= github.com/aws/aws-sdk-go-v2/service/kms v1.20.2/go.mod h1:vdqtUOdVuf5ooy+hJ2GnzqNo94xiAA9s1xbZ1hQgRE0= -github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.14.12 h1:vxOcOeqRTsO9ru0E5hkbhAeIdpYtizuoNEkLZuqm5ek= -github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.14.12/go.mod h1:xmV0oIDDFg4i3vNjRfwRAl1ZGpNsEj06gLYpFT+hwpI= +github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.14.13 h1:INNEByjR77yjugBQPVXkDTleLf5AIvxUslT1N3MG2So= +github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.14.13/go.mod h1:xmV0oIDDFg4i3vNjRfwRAl1ZGpNsEj06gLYpFT+hwpI= github.com/aws/aws-sdk-go-v2/service/s3 v1.30.2/go.mod h1:SXDHd6fI2RhqB7vmAzyYQCTQnpZrIprVJvYxpzW3JAM= -github.com/aws/aws-sdk-go-v2/service/s3 v1.34.0 h1:2qt8zaVqQCMpnQHBB+PAbfSSXgMl9+zpTRNDHmachJk= -github.com/aws/aws-sdk-go-v2/service/s3 v1.34.0/go.mod h1:aVbf0sko/TsLWHx30c/uVu7c62+0EAJ3vbxaJga0xCw= +github.com/aws/aws-sdk-go-v2/service/s3 v1.35.0 h1:ya7fmrN2fE7s1P2gaPbNg5MTkERVWfsH8ToP1YC4Z9o= +github.com/aws/aws-sdk-go-v2/service/s3 v1.35.0/go.mod h1:aVbf0sko/TsLWHx30c/uVu7c62+0EAJ3vbxaJga0xCw= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.18.3/go.mod h1:hqPcyOuLU6yWIbLy3qMnQnmidgKuIEwqIlW6+chYnog= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.19.9 h1:cLMyxvdb04nboUtwJl8GgyAbA25Hu7dYE/4/DV+Ku9M= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.19.9/go.mod h1:ezn6mzIRqTPdAbDpm03dx4y9g6rvGRb2q33wS76dCxw= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.19.10 h1:eW8zPSh7ZLzb7029xCsIEFbnxLvNHPTt7aWwdKjNJc8= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.19.10/go.mod h1:ezn6mzIRqTPdAbDpm03dx4y9g6rvGRb2q33wS76dCxw= github.com/aws/aws-sdk-go-v2/service/sns v1.20.2/go.mod h1:VN2n9SOMS1lNbh5YD7o+ho0/rgfifSrK//YYNiVVF5E= github.com/aws/aws-sdk-go-v2/service/sqs v1.20.2/go.mod h1:1ttxGjUHZliCQMpPss1sU5+Ph/5NvdMFRzr96bv8gm0= github.com/aws/aws-sdk-go-v2/service/ssm v1.35.2/go.mod h1:VLSz2SHUKYFSOlXB/GlXoLU6KPYQJAbw7I20TDJdyws= github.com/aws/aws-sdk-go-v2/service/sso v1.12.1/go.mod h1:IgV8l3sj22nQDd5qcAGY0WenwCzCphqdbFOpfktZPrI= -github.com/aws/aws-sdk-go-v2/service/sso v1.12.11 h1:cNrMc266RsZJ8V1u1OQQONKcf9HmfxQFqgcpY7ZJBhY= -github.com/aws/aws-sdk-go-v2/service/sso v1.12.11/go.mod h1:HuCOxYsF21eKrerARYO6HapNeh9GBNq7fius2AcwodY= +github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 h1:nneMBM2p79PGWBQovYO/6Xnc2ryRMw3InnDJq1FHkSY= +github.com/aws/aws-sdk-go-v2/service/sso v1.12.12/go.mod h1:HuCOxYsF21eKrerARYO6HapNeh9GBNq7fius2AcwodY= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.1/go.mod h1:O1YSOg3aekZibh2SngvCRRG+cRHKKlYgxf/JBF/Kr/k= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.11 h1:h2VhtCE5PBiJefmlVCjJRSzBfFcQeAE10SXIGkXw1jQ= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.11/go.mod h1:E4VrHCPzmVB/KFXtqBGKb3c8zpbNBgKe3fisDNLAW5w= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 h1:2qTR7IFk7/0IN/adSFhYu9Xthr0zVFTgBrmPldILn80= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12/go.mod h1:E4VrHCPzmVB/KFXtqBGKb3c8zpbNBgKe3fisDNLAW5w= github.com/aws/aws-sdk-go-v2/service/sts v1.18.3/go.mod h1:b+psTJn33Q4qGoDaM7ZiOVVG8uVjGI6HaZ8WBHdgDgU= -github.com/aws/aws-sdk-go-v2/service/sts v1.19.1 h1:ehPTnLR/es8TL1fpBfq8qw9cAwOpQr47fLmZD9yhHjk= -github.com/aws/aws-sdk-go-v2/service/sts v1.19.1/go.mod h1:dp0yLPsLBOi++WTxzCjA/oZqi6NPIhoR+uF7GeMU9eg= +github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 h1:XFJ2Z6sNUUcAz9poj+245DMkrHE4h2j5I9/xD50RHfE= +github.com/aws/aws-sdk-go-v2/service/sts v1.19.2/go.mod h1:dp0yLPsLBOi++WTxzCjA/oZqi6NPIhoR+uF7GeMU9eg= github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= @@ -1753,8 +1753,8 @@ github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= -github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1798,8 +1798,8 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O 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= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= +github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/prometheus v0.35.0/go.mod h1:7HaLx5kEPKJ0GDgbODG0fZgXbQ8K/XjZNJXQmbmgQlY= github.com/prometheus/prometheus v0.42.0/go.mod h1:Pfqb/MLnnR2KK+0vchiaH39jXxvLMBk+3lnIGP4N7Vk= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= @@ -1843,8 +1843,8 @@ github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod github.com/secsy/goftp v0.0.0-20200609142545-aa2de14babf4 h1:PT+ElG/UUFMfqy5HrxJxNzj3QBOf7dZwupeVC+mG1Lo= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= -github.com/sftpgo/sdk v0.1.5-0.20230614163902-b9133304e3d2 h1:LY1SFycc9ZNE9820cIQcpM1D7nSZLM7qfNynEWbMYfE= -github.com/sftpgo/sdk v0.1.5-0.20230614163902-b9133304e3d2/go.mod h1:TjeoMWS0JEXt9RukJveTnaiHj4+MVLtUiDC+mY++Odk= +github.com/sftpgo/sdk v0.1.5-0.20230616161947-bb4a056935b0 h1:GtEAHNYNOr7tknN2YYnn52irvpqtwPA/pFC7Gtm16hA= +github.com/sftpgo/sdk v0.1.5-0.20230616161947-bb4a056935b0/go.mod h1:TjeoMWS0JEXt9RukJveTnaiHj4+MVLtUiDC+mY++Odk= github.com/shirou/gopsutil/v3 v3.23.5 h1:5SgDCeQ0KW0S4N0znjeM/eFHXXOKyv2dVNgRq/c9P6Y= github.com/shirou/gopsutil/v3 v3.23.5/go.mod h1:Ng3Maa27Q2KARVJ0SPZF5NdrQSC3XHKP8IIWrHgMeLY= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= @@ -2305,7 +2305,7 @@ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= 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= @@ -2592,8 +2592,8 @@ golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= -golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg= +golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2670,8 +2670,8 @@ google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/ google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= -google.golang.org/api v0.127.0 h1:v7rj0vA0imM3Ou81k1eyFxQNScLzn71EyGnJDr+V/XI= -google.golang.org/api v0.127.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= +google.golang.org/api v0.128.0 h1:RjPESny5CnQRn9V6siglged+DZCgfu9l6mO9dkX9VOg= +google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 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= @@ -2866,8 +2866,8 @@ google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.52.1/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.0 h1:+y7Bs8rtMd07LeXmL3NxcTLn7mUkbKZqEpPhMNkwJEE= +google.golang.org/grpc v1.56.0/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/internal/common/connection.go b/internal/common/connection.go index ad005879..01800d2c 100644 --- a/internal/common/connection.go +++ b/internal/common/connection.go @@ -1316,8 +1316,7 @@ func (c *BaseConnection) GetTransferQuota() dataprovider.TransferQuota { } func (c *BaseConnection) checkUserQuota() (dataprovider.TransferQuota, int, int64) { - clientIP := c.GetRemoteIP() - ul, dl, total := c.User.GetDataTransferLimits(clientIP) + ul, dl, total := c.User.GetDataTransferLimits() result := dataprovider.TransferQuota{ ULSize: ul, DLSize: dl, diff --git a/internal/common/eventmanager.go b/internal/common/eventmanager.go index a0769bd8..b155a33f 100644 --- a/internal/common/eventmanager.go +++ b/internal/common/eventmanager.go @@ -1525,7 +1525,6 @@ func getUserForEventAction(user dataprovider.User) (dataprovider.User, error) { user.Filters.DisableFsChecks = false user.Filters.FilePatterns = nil user.Filters.BandwidthLimits = nil - user.Filters.DataTransferLimits = nil for k := range user.Permissions { user.Permissions[k] = []string{dataprovider.PermAny} } diff --git a/internal/common/protocol_test.go b/internal/common/protocol_test.go index 95d72d2d..6d9b6382 100644 --- a/internal/common/protocol_test.go +++ b/internal/common/protocol_test.go @@ -1548,12 +1548,6 @@ func TestVirtualFoldersQuotaRenameOverwrite(t *testing.T) { func TestQuotaRenameOverwrite(t *testing.T) { u := getTestUser() u.QuotaFiles = 100 - u.Filters.DataTransferLimits = []sdk.DataTransferLimit{ - { - Sources: []string{"10.8.0.0/8"}, - TotalDataTransfer: 1, - }, - } user, _, err := httpdtest.AddUser(u, http.StatusCreated) assert.NoError(t, err) conn, client, err := getSftpClient(user) diff --git a/internal/common/transfer_test.go b/internal/common/transfer_test.go index c3440e59..8f8203bd 100644 --- a/internal/common/transfer_test.go +++ b/internal/common/transfer_test.go @@ -332,41 +332,22 @@ func TestFTPMode(t *testing.T) { func TestTransferQuota(t *testing.T) { user := dataprovider.User{ BaseUser: sdk.BaseUser{ - TotalDataTransfer: -1, - UploadDataTransfer: -1, - DownloadDataTransfer: -1, + TotalDataTransfer: 3, + UploadDataTransfer: 2, + DownloadDataTransfer: 1, }, } - user.Filters.DataTransferLimits = []sdk.DataTransferLimit{ - { - Sources: []string{"127.0.0.1/32", "192.168.1.0/24"}, - TotalDataTransfer: 100, - UploadDataTransfer: 0, - DownloadDataTransfer: 0, - }, - { - Sources: []string{"172.16.0.0/24"}, - TotalDataTransfer: 0, - UploadDataTransfer: 120, - DownloadDataTransfer: 150, - }, - } - ul, dl, total := user.GetDataTransferLimits("127.0.1.1") + ul, dl, total := user.GetDataTransferLimits() + assert.Equal(t, int64(2*1048576), ul) + assert.Equal(t, int64(1*1048576), dl) + assert.Equal(t, int64(3*1048576), total) + user.TotalDataTransfer = -1 + user.UploadDataTransfer = -1 + user.DownloadDataTransfer = -1 + ul, dl, total = user.GetDataTransferLimits() assert.Equal(t, int64(0), ul) assert.Equal(t, int64(0), dl) assert.Equal(t, int64(0), total) - ul, dl, total = user.GetDataTransferLimits("127.0.0.1") - assert.Equal(t, int64(0), ul) - assert.Equal(t, int64(0), dl) - assert.Equal(t, int64(100*1048576), total) - ul, dl, total = user.GetDataTransferLimits("192.168.1.4") - assert.Equal(t, int64(0), ul) - assert.Equal(t, int64(0), dl) - assert.Equal(t, int64(100*1048576), total) - ul, dl, total = user.GetDataTransferLimits("172.16.0.2") - assert.Equal(t, int64(120*1048576), ul) - assert.Equal(t, int64(150*1048576), dl) - assert.Equal(t, int64(0), total) transferQuota := dataprovider.TransferQuota{} assert.True(t, transferQuota.HasDownloadSpace()) assert.True(t, transferQuota.HasUploadSpace()) diff --git a/internal/common/transferschecker.go b/internal/common/transferschecker.go index 4b9afcb2..0883176a 100644 --- a/internal/common/transferschecker.go +++ b/internal/common/transferschecker.go @@ -61,7 +61,7 @@ type baseTransferChecker struct { func (t *baseTransferChecker) isDataTransferExceeded(user dataprovider.User, transfer dataprovider.ActiveTransfer, ulSize, dlSize int64, ) bool { - ulQuota, dlQuota, totalQuota := user.GetDataTransferLimits(transfer.IP) + ulQuota, dlQuota, totalQuota := user.GetDataTransferLimits() if totalQuota > 0 { allowedSize := totalQuota - (user.UsedUploadDataTransfer + user.UsedDownloadDataTransfer) if ulSize+dlSize > allowedSize { diff --git a/internal/common/transferschecker_test.go b/internal/common/transferschecker_test.go index aadb9d3a..e27da903 100644 --- a/internal/common/transferschecker_test.go +++ b/internal/common/transferschecker_test.go @@ -622,17 +622,6 @@ func TestGetUsersForQuotaCheck(t *testing.T) { QuotaSize: 100, }, }, - Filters: dataprovider.UserFilters{ - BaseUserFilters: sdk.BaseUserFilters{ - DataTransferLimits: []sdk.DataTransferLimit{ - { - Sources: []string{"172.16.0.0/16"}, - UploadDataTransfer: 50, - DownloadDataTransfer: 80, - }, - }, - }, - }, } err = dataprovider.AddUser(&user, "", "", "") assert.NoError(t, err) @@ -660,14 +649,10 @@ func TestGetUsersForQuotaCheck(t *testing.T) { assert.Len(t, user.VirtualFolders, 0, user.Username) } } - ul, dl, total := user.GetDataTransferLimits("127.1.1.1") + ul, dl, total := user.GetDataTransferLimits() assert.Equal(t, int64(0), ul) assert.Equal(t, int64(0), dl) assert.Equal(t, int64(0), total) - ul, dl, total = user.GetDataTransferLimits("172.16.2.3") - assert.Equal(t, int64(50*1024*1024), ul) - assert.Equal(t, int64(80*1024*1024), dl) - assert.Equal(t, int64(0), total) } for i := 0; i < 40; i++ { diff --git a/internal/dataprovider/dataprovider.go b/internal/dataprovider/dataprovider.go index 42a45827..608b5f3c 100644 --- a/internal/dataprovider/dataprovider.go +++ b/internal/dataprovider/dataprovider.go @@ -2585,18 +2585,6 @@ func copyBaseUserFilters(in sdk.BaseUserFilters) sdk.BaseUserFilters { copy(bwLimit.Sources, limit.Sources) filters.BandwidthLimits = append(filters.BandwidthLimits, bwLimit) } - filters.DataTransferLimits = make([]sdk.DataTransferLimit, 0, len(in.DataTransferLimits)) - for _, limit := range in.DataTransferLimits { - dtLimit := sdk.DataTransferLimit{ - UploadDataTransfer: limit.UploadDataTransfer, - DownloadDataTransfer: limit.DownloadDataTransfer, - TotalDataTransfer: limit.TotalDataTransfer, - Sources: make([]string, 0, len(limit.Sources)), - } - dtLimit.Sources = make([]string, len(limit.Sources)) - copy(dtLimit.Sources, limit.Sources) - filters.DataTransferLimits = append(filters.DataTransferLimits, dtLimit) - } return filters } @@ -2943,26 +2931,6 @@ func validateBandwidthLimitsFilter(filters *sdk.BaseUserFilters) error { return nil } -func validateTransferLimitsFilter(filters *sdk.BaseUserFilters) error { - for idx, limit := range filters.DataTransferLimits { - filters.DataTransferLimits[idx].Sources = util.RemoveDuplicates(limit.Sources, false) - if len(limit.Sources) == 0 { - return util.NewValidationError("no data transfer limit source specified") - } - for _, source := range limit.Sources { - _, _, err := net.ParseCIDR(source) - if err != nil { - return util.NewValidationError(fmt.Sprintf("could not parse data transfer limit source %q: %v", source, err)) - } - } - if limit.TotalDataTransfer > 0 { - filters.DataTransferLimits[idx].UploadDataTransfer = 0 - filters.DataTransferLimits[idx].DownloadDataTransfer = 0 - } - } - return nil -} - func updateFiltersValues(filters *sdk.BaseUserFilters) { if filters.StartDirectory != "" { filters.StartDirectory = util.CleanPath(filters.StartDirectory) @@ -2998,9 +2966,6 @@ func validateBaseFilters(filters *sdk.BaseUserFilters) error { if err := validateBandwidthLimitsFilter(filters); err != nil { return err } - if err := validateTransferLimitsFilter(filters); err != nil { - return err - } if len(filters.DeniedLoginMethods) >= len(ValidLoginMethods) { return util.NewValidationError("invalid denied_login_methods") } diff --git a/internal/dataprovider/user.go b/internal/dataprovider/user.go index 5cc7b1a5..c8e1141b 100644 --- a/internal/dataprovider/user.go +++ b/internal/dataprovider/user.go @@ -1289,39 +1289,12 @@ func (u *User) HasQuotaRestrictions() bool { // HasTransferQuotaRestrictions returns true if there are any data transfer restrictions func (u *User) HasTransferQuotaRestrictions() bool { - if len(u.Filters.DataTransferLimits) > 0 { - return true - } return u.UploadDataTransfer > 0 || u.TotalDataTransfer > 0 || u.DownloadDataTransfer > 0 } // GetDataTransferLimits returns upload, download and total data transfer limits -func (u *User) GetDataTransferLimits(clientIP string) (int64, int64, int64) { +func (u *User) GetDataTransferLimits() (int64, int64, int64) { var total, ul, dl int64 - if len(u.Filters.DataTransferLimits) > 0 { - ip := net.ParseIP(clientIP) - if ip != nil { - for _, limit := range u.Filters.DataTransferLimits { - for _, source := range limit.Sources { - _, ipNet, err := net.ParseCIDR(source) - if err == nil { - if ipNet.Contains(ip) { - if limit.TotalDataTransfer > 0 { - total = limit.TotalDataTransfer * 1048576 - } - if limit.DownloadDataTransfer > 0 { - dl = limit.DownloadDataTransfer * 1048576 - } - if limit.UploadDataTransfer > 0 { - ul = limit.UploadDataTransfer * 1048576 - } - return ul, dl, total - } - } - } - } - } - } if u.TotalDataTransfer > 0 { total = u.TotalDataTransfer * 1048576 } @@ -1825,7 +1798,6 @@ func (u *User) mergeAdditiveProperties(group *Group, groupType int, replacer *st u.mergePermissions(group, groupType, replacer) u.mergeFilePatterns(group, groupType, replacer) u.Filters.BandwidthLimits = append(u.Filters.BandwidthLimits, group.UserSettings.Filters.BandwidthLimits...) - u.Filters.DataTransferLimits = append(u.Filters.DataTransferLimits, group.UserSettings.Filters.DataTransferLimits...) u.Filters.AllowedIP = append(u.Filters.AllowedIP, group.UserSettings.Filters.AllowedIP...) u.Filters.DeniedIP = append(u.Filters.DeniedIP, group.UserSettings.Filters.DeniedIP...) u.Filters.DeniedLoginMethods = append(u.Filters.DeniedLoginMethods, group.UserSettings.Filters.DeniedLoginMethods...) diff --git a/internal/httpd/httpd_test.go b/internal/httpd/httpd_test.go index c69c4410..a90bbc6b 100644 --- a/internal/httpd/httpd_test.go +++ b/internal/httpd/httpd_test.go @@ -2627,103 +2627,6 @@ func TestEventRuleValidation(t *testing.T) { assert.Contains(t, string(resp), "invalid Identity Provider login event") } -func TestUserTransferLimits(t *testing.T) { - u := getTestUser() - u.TotalDataTransfer = 100 - u.Filters.DataTransferLimits = []sdk.DataTransferLimit{ - { - Sources: nil, - }, - } - _, resp, err := httpdtest.AddUser(u, http.StatusBadRequest) - assert.NoError(t, err, string(resp)) - assert.Contains(t, string(resp), "Validation error: no data transfer limit source specified") - u.Filters.DataTransferLimits = []sdk.DataTransferLimit{ - { - Sources: []string{"a"}, - }, - } - _, resp, err = httpdtest.AddUser(u, http.StatusBadRequest) - assert.NoError(t, err, string(resp)) - assert.Contains(t, string(resp), "Validation error: could not parse data transfer limit source") - u.Filters.DataTransferLimits = []sdk.DataTransferLimit{ - { - Sources: []string{"127.0.0.1/32"}, - UploadDataTransfer: 120, - DownloadDataTransfer: 140, - }, - { - Sources: []string{"192.168.0.0/24", "192.168.1.0/24"}, - TotalDataTransfer: 400, - }, - { - Sources: []string{"10.0.0.0/8"}, - }, - } - user, resp, err := httpdtest.AddUser(u, http.StatusCreated) - assert.NoError(t, err, string(resp)) - assert.Len(t, user.Filters.DataTransferLimits, 3) - assert.Equal(t, u.Filters.DataTransferLimits, user.Filters.DataTransferLimits) - up, down, total := user.GetDataTransferLimits("1.1.1.1") - assert.Equal(t, user.TotalDataTransfer*1024*1024, total) - assert.Equal(t, user.UploadDataTransfer*1024*1024, up) - assert.Equal(t, user.DownloadDataTransfer*1024*1024, down) - up, down, total = user.GetDataTransferLimits("127.0.0.1") - assert.Equal(t, user.Filters.DataTransferLimits[0].TotalDataTransfer*1024*1024, total) - assert.Equal(t, user.Filters.DataTransferLimits[0].UploadDataTransfer*1024*1024, up) - assert.Equal(t, user.Filters.DataTransferLimits[0].DownloadDataTransfer*1024*1024, down) - up, down, total = user.GetDataTransferLimits("192.168.1.6") - assert.Equal(t, user.Filters.DataTransferLimits[1].TotalDataTransfer*1024*1024, total) - assert.Equal(t, user.Filters.DataTransferLimits[1].UploadDataTransfer*1024*1024, up) - assert.Equal(t, user.Filters.DataTransferLimits[1].DownloadDataTransfer*1024*1024, down) - up, down, total = user.GetDataTransferLimits("10.1.2.3") - assert.Equal(t, user.Filters.DataTransferLimits[2].TotalDataTransfer*1024*1024, total) - assert.Equal(t, user.Filters.DataTransferLimits[2].UploadDataTransfer*1024*1024, up) - assert.Equal(t, user.Filters.DataTransferLimits[2].DownloadDataTransfer*1024*1024, down) - - connID := xid.New().String() - localAddr := "::1" - conn := common.NewBaseConnection(connID, common.ProtocolHTTP, localAddr, "1.1.1.2", user) - transferQuota := conn.GetTransferQuota() - assert.Equal(t, user.TotalDataTransfer*1024*1024, transferQuota.AllowedTotalSize) - assert.Equal(t, user.UploadDataTransfer*1024*1024, transferQuota.AllowedULSize) - assert.Equal(t, user.DownloadDataTransfer*1024*1024, transferQuota.AllowedDLSize) - - conn = common.NewBaseConnection(connID, common.ProtocolHTTP, localAddr, "127.0.0.1", user) - transferQuota = conn.GetTransferQuota() - assert.Equal(t, user.Filters.DataTransferLimits[0].TotalDataTransfer*1024*1024, transferQuota.AllowedTotalSize) - assert.Equal(t, user.Filters.DataTransferLimits[0].UploadDataTransfer*1024*1024, transferQuota.AllowedULSize) - assert.Equal(t, user.Filters.DataTransferLimits[0].DownloadDataTransfer*1024*1024, transferQuota.AllowedDLSize) - - conn = common.NewBaseConnection(connID, common.ProtocolHTTP, localAddr, "192.168.1.5", user) - transferQuota = conn.GetTransferQuota() - assert.Equal(t, user.Filters.DataTransferLimits[1].TotalDataTransfer*1024*1024, transferQuota.AllowedTotalSize) - assert.Equal(t, user.Filters.DataTransferLimits[1].UploadDataTransfer*1024*1024, transferQuota.AllowedULSize) - assert.Equal(t, user.Filters.DataTransferLimits[1].DownloadDataTransfer*1024*1024, transferQuota.AllowedDLSize) - - u.UsedDownloadDataTransfer = 10 * 1024 * 1024 - u.UsedUploadDataTransfer = 5 * 1024 * 1024 - _, err = httpdtest.UpdateTransferQuotaUsage(u, "", http.StatusOK) - assert.NoError(t, err) - - conn = common.NewBaseConnection(connID, common.ProtocolHTTP, localAddr, "192.168.1.6", user) - transferQuota = conn.GetTransferQuota() - assert.Equal(t, (user.Filters.DataTransferLimits[1].TotalDataTransfer-15)*1024*1024, transferQuota.AllowedTotalSize) - assert.Equal(t, user.Filters.DataTransferLimits[1].UploadDataTransfer*1024*1024, transferQuota.AllowedULSize) - assert.Equal(t, user.Filters.DataTransferLimits[1].DownloadDataTransfer*1024*1024, transferQuota.AllowedDLSize) - - conn = common.NewBaseConnection(connID, common.ProtocolHTTP, localAddr, "10.8.3.4", user) - transferQuota = conn.GetTransferQuota() - assert.Equal(t, int64(0), transferQuota.AllowedTotalSize) - assert.Equal(t, int64(0), transferQuota.AllowedULSize) - assert.Equal(t, int64(0), transferQuota.AllowedDLSize) - - err = os.RemoveAll(user.GetHomeDir()) - assert.NoError(t, err) - _, err = httpdtest.RemoveUser(user, http.StatusOK) - assert.NoError(t, err) -} - func TestUserBandwidthLimits(t *testing.T) { u := getTestUser() u.UploadBandwidth = 128 @@ -19686,49 +19589,6 @@ func TestWebUserAddMock(t *testing.T) { assert.Contains(t, rr.Body.String(), "Validation error: could not parse bandwidth limit source") form.Set("bandwidth_limit_sources1", "127.0.0.1/32") form.Set("upload_bandwidth_source1", "-1") - form.Set("data_transfer_limit_sources0", "127.0.1.1") - b, contentType, _ = getMultipartFormData(form, "", "") - req, _ = http.NewRequest(http.MethodPost, webUserPath, &b) - setJWTCookieForReq(req, webToken) - req.Header.Set("Content-Type", contentType) - rr = executeRequest(req) - checkResponseCode(t, http.StatusOK, rr) - assert.Contains(t, rr.Body.String(), "could not parse data transfer limit source") - form.Set("data_transfer_limit_sources0", "127.0.1.1/32") - form.Set("upload_data_transfer_source0", "a") - b, contentType, _ = getMultipartFormData(form, "", "") - req, _ = http.NewRequest(http.MethodPost, webUserPath, &b) - setJWTCookieForReq(req, webToken) - req.Header.Set("Content-Type", contentType) - rr = executeRequest(req) - checkResponseCode(t, http.StatusOK, rr) - assert.Contains(t, rr.Body.String(), "invalid upload_data_transfer_source") - form.Set("upload_data_transfer_source0", "0") - form.Set("download_data_transfer_source0", "a") - b, contentType, _ = getMultipartFormData(form, "", "") - req, _ = http.NewRequest(http.MethodPost, webUserPath, &b) - setJWTCookieForReq(req, webToken) - req.Header.Set("Content-Type", contentType) - rr = executeRequest(req) - checkResponseCode(t, http.StatusOK, rr) - assert.Contains(t, rr.Body.String(), "invalid download_data_transfer_source") - form.Set("download_data_transfer_source0", "0") - form.Set("total_data_transfer_source0", "a") - b, contentType, _ = getMultipartFormData(form, "", "") - req, _ = http.NewRequest(http.MethodPost, webUserPath, &b) - setJWTCookieForReq(req, webToken) - req.Header.Set("Content-Type", contentType) - rr = executeRequest(req) - checkResponseCode(t, http.StatusOK, rr) - assert.Contains(t, rr.Body.String(), "invalid total_data_transfer_source") - form.Set("total_data_transfer_source0", "0") - form.Set("data_transfer_limit_sources10", "192.168.5.0/24, 10.8.0.0/16") - form.Set("download_data_transfer_source10", "100") - form.Set("upload_data_transfer_source10", "120") - form.Set("data_transfer_limit_sources12", "192.168.3.0/24, 10.8.2.0/24,::1/64") - form.Set("download_data_transfer_source12", "100") - form.Set("upload_data_transfer_source12", "120") - form.Set("total_data_transfer_source12", "200") // invalid external auth cache size form.Set("external_auth_cache_time", "a") b, contentType, _ = getMultipartFormData(form, "", "") @@ -19850,30 +19710,6 @@ func TestWebUserAddMock(t *testing.T) { } } } - if assert.Len(t, newUser.Filters.DataTransferLimits, 3) { - for _, dtLimit := range newUser.Filters.DataTransferLimits { - switch len(dtLimit.Sources) { - case 3: - assert.Equal(t, "192.168.3.0/24", dtLimit.Sources[0]) - assert.Equal(t, "10.8.2.0/24", dtLimit.Sources[1]) - assert.Equal(t, "::1/64", dtLimit.Sources[2]) - assert.Equal(t, int64(0), dtLimit.UploadDataTransfer) - assert.Equal(t, int64(0), dtLimit.DownloadDataTransfer) - assert.Equal(t, int64(200), dtLimit.TotalDataTransfer) - case 2: - assert.Equal(t, "192.168.5.0/24", dtLimit.Sources[0]) - assert.Equal(t, "10.8.0.0/16", dtLimit.Sources[1]) - assert.Equal(t, int64(120), dtLimit.UploadDataTransfer) - assert.Equal(t, int64(100), dtLimit.DownloadDataTransfer) - assert.Equal(t, int64(0), dtLimit.TotalDataTransfer) - case 1: - assert.Equal(t, "127.0.1.1/32", dtLimit.Sources[0]) - assert.Equal(t, int64(0), dtLimit.UploadDataTransfer) - assert.Equal(t, int64(0), dtLimit.DownloadDataTransfer) - assert.Equal(t, int64(0), dtLimit.TotalDataTransfer) - } - } - } assert.Len(t, newUser.Groups, 3) assert.Equal(t, sdk.TLSUsernameNone, newUser.Filters.TLSUsername) req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, newUser.Username), nil) diff --git a/internal/httpd/internal_test.go b/internal/httpd/internal_test.go index 2443da78..f7f7702e 100644 --- a/internal/httpd/internal_test.go +++ b/internal/httpd/internal_test.go @@ -3365,6 +3365,92 @@ func TestGetLogEventString(t *testing.T) { assert.Empty(t, getLogEventString(0)) } +func TestUserQuotaUsage(t *testing.T) { + usage := userQuotaUsage{ + QuotaSize: 100, + } + require.True(t, usage.HasQuotaInfo()) + require.NotEmpty(t, usage.GetQuotaSize()) + providerConf := dataprovider.GetProviderConfig() + quotaTracking := dataprovider.GetQuotaTracking() + providerConf.TrackQuota = 0 + err := dataprovider.Close() + assert.NoError(t, err) + err = dataprovider.Initialize(providerConf, configDir, true) + assert.NoError(t, err) + err = dataprovider.Close() + assert.NoError(t, err) + assert.False(t, usage.HasQuotaInfo()) + providerConf.TrackQuota = quotaTracking + err = dataprovider.Initialize(providerConf, configDir, true) + assert.NoError(t, err) + usage.QuotaSize = 0 + assert.False(t, usage.HasQuotaInfo()) + assert.Empty(t, usage.GetQuotaSize()) + assert.Equal(t, 0, usage.GetQuotaSizePercentage()) + assert.False(t, usage.IsQuotaSizeLow()) + assert.False(t, usage.IsDiskQuotaLow()) + assert.False(t, usage.IsQuotaLow()) + usage.UsedQuotaSize = 9 + assert.NotEmpty(t, usage.GetQuotaSize()) + usage.QuotaSize = 10 + assert.True(t, usage.IsQuotaSizeLow()) + assert.True(t, usage.IsDiskQuotaLow()) + assert.True(t, usage.IsQuotaLow()) + usage.DownloadDataTransfer = 1 + assert.True(t, usage.HasQuotaInfo()) + assert.True(t, usage.HasTranferQuota()) + assert.Empty(t, usage.GetQuotaFiles()) + assert.Equal(t, 0, usage.GetQuotaFilesPercentage()) + usage.QuotaFiles = 1 + assert.NotEmpty(t, usage.GetQuotaFiles()) + usage.QuotaFiles = 0 + usage.UsedQuotaFiles = 9 + assert.NotEmpty(t, usage.GetQuotaFiles()) + usage.QuotaFiles = 10 + usage.DownloadDataTransfer = 0 + assert.True(t, usage.IsQuotaFilesLow()) + assert.True(t, usage.IsDiskQuotaLow()) + assert.False(t, usage.IsTotalTransferQuotaLow()) + assert.False(t, usage.IsUploadTransferQuotaLow()) + assert.False(t, usage.IsDownloadTransferQuotaLow()) + assert.Equal(t, 0, usage.GetTotalTransferQuotaPercentage()) + assert.Equal(t, 0, usage.GetUploadTransferQuotaPercentage()) + assert.Equal(t, 0, usage.GetDownloadTransferQuotaPercentage()) + assert.Empty(t, usage.GetTotalTransferQuota()) + assert.Empty(t, usage.GetUploadTransferQuota()) + assert.Empty(t, usage.GetDownloadTransferQuota()) + usage.TotalDataTransfer = 3 + usage.UsedUploadDataTransfer = 1 * 1048576 + assert.NotEmpty(t, usage.GetTotalTransferQuota()) + usage.TotalDataTransfer = 0 + assert.NotEmpty(t, usage.GetTotalTransferQuota()) + assert.NotEmpty(t, usage.GetUploadTransferQuota()) + usage.UploadDataTransfer = 2 + assert.NotEmpty(t, usage.GetUploadTransferQuota()) + usage.UsedDownloadDataTransfer = 1 * 1048576 + assert.NotEmpty(t, usage.GetDownloadTransferQuota()) + usage.DownloadDataTransfer = 2 + assert.NotEmpty(t, usage.GetDownloadTransferQuota()) + assert.False(t, usage.IsTransferQuotaLow()) + usage.UsedDownloadDataTransfer = 8 * 1048576 + usage.TotalDataTransfer = 10 + assert.True(t, usage.IsTotalTransferQuotaLow()) + assert.True(t, usage.IsTransferQuotaLow()) + usage.TotalDataTransfer = 0 + usage.UploadDataTransfer = 0 + usage.DownloadDataTransfer = 0 + assert.False(t, usage.IsTransferQuotaLow()) + usage.UploadDataTransfer = 10 + usage.UsedUploadDataTransfer = 9 * 1048576 + assert.True(t, usage.IsUploadTransferQuotaLow()) + assert.True(t, usage.IsTransferQuotaLow()) + usage.DownloadDataTransfer = 10 + usage.UsedDownloadDataTransfer = 9 * 1048576 + assert.True(t, usage.IsDownloadTransferQuotaLow()) + assert.True(t, usage.IsTransferQuotaLow()) +} + func isSharedProviderSupported() bool { // SQLite shares the implementation with other SQL-based provider but it makes no sense // to use it outside test cases diff --git a/internal/httpd/webadmin.go b/internal/httpd/webadmin.go index 4953e681..a6f7b5ca 100644 --- a/internal/httpd/webadmin.go +++ b/internal/httpd/webadmin.go @@ -1353,50 +1353,6 @@ func getUserPermissionsFromPostFields(r *http.Request) map[string][]string { return permissions } -func getDataTransferLimitsFromPostFields(r *http.Request) ([]sdk.DataTransferLimit, error) { - var result []sdk.DataTransferLimit - - for k := range r.Form { - if strings.HasPrefix(k, "data_transfer_limit_sources") { - sources := getSliceFromDelimitedValues(r.Form.Get(k), ",") - if len(sources) > 0 { - dtLimit := sdk.DataTransferLimit{ - Sources: sources, - } - idx := strings.TrimPrefix(k, "data_transfer_limit_sources") - ul := r.Form.Get(fmt.Sprintf("upload_data_transfer_source%v", idx)) - dl := r.Form.Get(fmt.Sprintf("download_data_transfer_source%v", idx)) - total := r.Form.Get(fmt.Sprintf("total_data_transfer_source%v", idx)) - if ul != "" { - dataUL, err := strconv.ParseInt(ul, 10, 64) - if err != nil { - return result, fmt.Errorf("invalid upload_data_transfer_source%v %q: %w", idx, ul, err) - } - dtLimit.UploadDataTransfer = dataUL - } - if dl != "" { - dataDL, err := strconv.ParseInt(dl, 10, 64) - if err != nil { - return result, fmt.Errorf("invalid download_data_transfer_source%v %q: %w", idx, dl, err) - } - dtLimit.DownloadDataTransfer = dataDL - } - if total != "" { - dataTotal, err := strconv.ParseInt(total, 10, 64) - if err != nil { - return result, fmt.Errorf("invalid total_data_transfer_source%v %q: %w", idx, total, err) - } - dtLimit.TotalDataTransfer = dataTotal - } - - result = append(result, dtLimit) - } - } - } - - return result, nil -} - func getBandwidthLimitsFromPostFields(r *http.Request) ([]sdk.BandwidthLimit, error) { var result []sdk.BandwidthLimit @@ -1534,10 +1490,6 @@ func getFiltersFromUserPostFields(r *http.Request) (sdk.BaseUserFilters, error) if err != nil { return filters, err } - dtLimits, err := getDataTransferLimitsFromPostFields(r) - if err != nil { - return filters, err - } maxFileSize, err := util.ParseBytes(r.Form.Get("max_upload_file_size")) if err != nil { return filters, fmt.Errorf("invalid max upload file size: %w", err) @@ -1558,7 +1510,6 @@ func getFiltersFromUserPostFields(r *http.Request) (sdk.BaseUserFilters, error) filters.FTPSecurity = 1 } filters.BandwidthLimits = bwLimits - filters.DataTransferLimits = dtLimits filters.AllowedIP = getSliceFromDelimitedValues(r.Form.Get("allowed_ip"), ",") filters.DeniedIP = getSliceFromDelimitedValues(r.Form.Get("denied_ip"), ",") filters.DeniedLoginMethods = r.Form["denied_login_methods"] diff --git a/internal/httpd/webclient.go b/internal/httpd/webclient.go index 0ff8d731..ff653582 100644 --- a/internal/httpd/webclient.go +++ b/internal/httpd/webclient.go @@ -21,6 +21,7 @@ import ( "fmt" "html/template" "io" + "math" "net/http" "net/url" "os" @@ -155,6 +156,7 @@ type filesPage struct { Error string Paths []dirMapping HasIntegrations bool + QuotaUsage *userQuotaUsage } type shareLoginPage struct { @@ -229,6 +231,185 @@ type clientSharePage struct { IsAdd bool } +type userQuotaUsage struct { + QuotaSize int64 + QuotaFiles int + UsedQuotaSize int64 + UsedQuotaFiles int + UploadDataTransfer int64 + DownloadDataTransfer int64 + TotalDataTransfer int64 + UsedUploadDataTransfer int64 + UsedDownloadDataTransfer int64 +} + +func (u *userQuotaUsage) HasQuotaInfo() bool { + if dataprovider.GetQuotaTracking() == 0 { + return false + } + if u.HasDiskQuota() { + return true + } + return u.HasTranferQuota() +} + +func (u *userQuotaUsage) HasDiskQuota() bool { + if u.QuotaSize > 0 || u.UsedQuotaSize > 0 { + return true + } + return u.QuotaFiles > 0 || u.UsedQuotaFiles > 0 +} + +func (u *userQuotaUsage) HasTranferQuota() bool { + if u.TotalDataTransfer > 0 || u.UploadDataTransfer > 0 || u.DownloadDataTransfer > 0 { + return true + } + return u.UsedDownloadDataTransfer > 0 || u.UsedUploadDataTransfer > 0 +} + +func (u *userQuotaUsage) GetQuotaSize() string { + if u.QuotaSize > 0 { + return fmt.Sprintf("%s/%s", util.ByteCountIEC(u.UsedQuotaSize), util.ByteCountIEC(u.QuotaSize)) + } + if u.UsedQuotaSize > 0 { + return util.ByteCountIEC(u.UsedQuotaSize) + } + return "" +} + +func (u *userQuotaUsage) GetQuotaFiles() string { + if u.QuotaFiles > 0 { + return fmt.Sprintf("%d/%d", u.UsedQuotaFiles, u.QuotaFiles) + } + if u.UsedQuotaFiles > 0 { + return strconv.FormatInt(int64(u.UsedQuotaFiles), 10) + } + return "" +} + +func (u *userQuotaUsage) GetQuotaSizePercentage() int { + if u.QuotaSize > 0 { + return int(math.Round(100 * float64(u.UsedQuotaSize) / float64(u.QuotaSize))) + } + return 0 +} + +func (u *userQuotaUsage) GetQuotaFilesPercentage() int { + if u.QuotaFiles > 0 { + return int(math.Round(100 * float64(u.UsedQuotaFiles) / float64(u.QuotaFiles))) + } + return 0 +} + +func (u *userQuotaUsage) IsQuotaSizeLow() bool { + return u.GetQuotaSizePercentage() > 85 +} + +func (u *userQuotaUsage) IsQuotaFilesLow() bool { + return u.GetQuotaFilesPercentage() > 85 +} + +func (u *userQuotaUsage) IsDiskQuotaLow() bool { + return u.IsQuotaSizeLow() || u.IsQuotaFilesLow() +} + +func (u *userQuotaUsage) GetTotalTransferQuota() string { + total := u.UsedUploadDataTransfer + u.UsedDownloadDataTransfer + if u.TotalDataTransfer > 0 { + return fmt.Sprintf("%s/%s", util.ByteCountIEC(total), util.ByteCountIEC(u.TotalDataTransfer*1048576)) + } + if total > 0 { + return util.ByteCountIEC(total) + } + return "" +} + +func (u *userQuotaUsage) GetUploadTransferQuota() string { + if u.UploadDataTransfer > 0 { + return fmt.Sprintf("%s/%s", util.ByteCountIEC(u.UsedUploadDataTransfer), + util.ByteCountIEC(u.UploadDataTransfer*1048576)) + } + if u.UsedUploadDataTransfer > 0 { + return util.ByteCountIEC(u.UsedUploadDataTransfer) + } + return "" +} + +func (u *userQuotaUsage) GetDownloadTransferQuota() string { + if u.DownloadDataTransfer > 0 { + return fmt.Sprintf("%s/%s", util.ByteCountIEC(u.UsedDownloadDataTransfer), + util.ByteCountIEC(u.DownloadDataTransfer*1048576)) + } + if u.UsedDownloadDataTransfer > 0 { + return util.ByteCountIEC(u.UsedDownloadDataTransfer) + } + return "" +} + +func (u *userQuotaUsage) GetTotalTransferQuotaPercentage() int { + if u.TotalDataTransfer > 0 { + return int(math.Round(100 * float64(u.UsedDownloadDataTransfer+u.UsedUploadDataTransfer) / float64(u.TotalDataTransfer*1048576))) + } + return 0 +} + +func (u *userQuotaUsage) GetUploadTransferQuotaPercentage() int { + if u.UploadDataTransfer > 0 { + return int(math.Round(100 * float64(u.UsedUploadDataTransfer) / float64(u.UploadDataTransfer*1048576))) + } + return 0 +} + +func (u *userQuotaUsage) GetDownloadTransferQuotaPercentage() int { + if u.DownloadDataTransfer > 0 { + return int(math.Round(100 * float64(u.UsedDownloadDataTransfer) / float64(u.DownloadDataTransfer*1048576))) + } + return 0 +} + +func (u *userQuotaUsage) IsTotalTransferQuotaLow() bool { + if u.TotalDataTransfer > 0 { + return u.GetTotalTransferQuotaPercentage() > 85 + } + return false +} + +func (u *userQuotaUsage) IsUploadTransferQuotaLow() bool { + if u.UploadDataTransfer > 0 { + return u.GetUploadTransferQuotaPercentage() > 85 + } + return false +} + +func (u *userQuotaUsage) IsDownloadTransferQuotaLow() bool { + if u.DownloadDataTransfer > 0 { + return u.GetDownloadTransferQuotaPercentage() > 85 + } + return false +} + +func (u *userQuotaUsage) IsTransferQuotaLow() bool { + return u.IsTotalTransferQuotaLow() || u.IsUploadTransferQuotaLow() || u.IsDownloadTransferQuotaLow() +} + +func (u *userQuotaUsage) IsQuotaLow() bool { + return u.IsDiskQuotaLow() || u.IsTransferQuotaLow() +} + +func newUserQuotaUsage(u *dataprovider.User) *userQuotaUsage { + return &userQuotaUsage{ + QuotaSize: u.QuotaSize, + QuotaFiles: u.QuotaFiles, + UsedQuotaSize: u.UsedQuotaSize, + UsedQuotaFiles: u.UsedQuotaFiles, + TotalDataTransfer: u.TotalDataTransfer, + UploadDataTransfer: u.UploadDataTransfer, + DownloadDataTransfer: u.DownloadDataTransfer, + UsedUploadDataTransfer: u.UsedUploadDataTransfer, + UsedDownloadDataTransfer: u.UsedDownloadDataTransfer, + } +} + func getFileObjectURL(baseDir, name, baseWebPath string) string { return fmt.Sprintf("%v?path=%v&_=%v", baseWebPath, url.QueryEscape(path.Join(baseDir, name)), time.Now().UTC().Unix()) } @@ -595,7 +776,7 @@ func (s *httpdServer) renderUploadToSharePage(w http.ResponseWriter, r *http.Req renderClientTemplate(w, templateUploadToShare, data) } -func (s *httpdServer) renderFilesPage(w http.ResponseWriter, r *http.Request, dirName, error string, user dataprovider.User, +func (s *httpdServer) renderFilesPage(w http.ResponseWriter, r *http.Request, dirName, error string, user *dataprovider.User, hasIntegrations bool, ) { data := filesPage{ @@ -615,6 +796,7 @@ func (s *httpdServer) renderFilesPage(w http.ResponseWriter, r *http.Request, di CanShare: user.CanManageShares(), HasIntegrations: hasIntegrations, Paths: getDirMapping(dirName, webClientFilesPath), + QuotaUsage: newUserQuotaUsage(user), } renderClientTemplate(w, templateClientFiles, data) } @@ -964,11 +1146,11 @@ func (s *httpdServer) handleClientGetFiles(w http.ResponseWriter, r *http.Reques } if err != nil { s.renderFilesPage(w, r, path.Dir(name), fmt.Sprintf("unable to stat file %q: %v", name, err), - user, len(s.binding.WebClientIntegrations) > 0) + &user, len(s.binding.WebClientIntegrations) > 0) return } if info.IsDir() { - s.renderFilesPage(w, r, name, "", user, len(s.binding.WebClientIntegrations) > 0) + s.renderFilesPage(w, r, name, "", &user, len(s.binding.WebClientIntegrations) > 0) return } if status, err := downloadFile(w, r, connection, name, info, false, nil); err != nil && status != 0 { @@ -977,7 +1159,7 @@ func (s *httpdServer) handleClientGetFiles(w http.ResponseWriter, r *http.Reques s.renderClientMessagePage(w, r, http.StatusText(status), "", status, err, "") return } - s.renderFilesPage(w, r, path.Dir(name), err.Error(), user, len(s.binding.WebClientIntegrations) > 0) + s.renderFilesPage(w, r, path.Dir(name), err.Error(), &user, len(s.binding.WebClientIntegrations) > 0) } } } diff --git a/internal/httpdtest/httpdtest.go b/internal/httpdtest/httpdtest.go index fc585173..1d185b80 100644 --- a/internal/httpdtest/httpdtest.go +++ b/internal/httpdtest/httpdtest.go @@ -2487,9 +2487,6 @@ func compareUserFilters(expected sdk.BaseUserFilters, actual sdk.BaseUserFilters if err := compareUserBandwidthLimitFilters(expected, actual); err != nil { return err } - if err := compareUserDataTransferLimitFilters(expected, actual); err != nil { - return err - } return compareUserFilePatternsFilters(expected, actual) } @@ -2505,30 +2502,6 @@ func checkFilterMatch(expected []string, actual []string) bool { return true } -func compareUserDataTransferLimitFilters(expected sdk.BaseUserFilters, actual sdk.BaseUserFilters) error { - if len(expected.DataTransferLimits) != len(actual.DataTransferLimits) { - return errors.New("data transfer limits filters mismatch") - } - for idx, l := range expected.DataTransferLimits { - if actual.DataTransferLimits[idx].UploadDataTransfer != l.UploadDataTransfer { - return errors.New("data transfer limit upload_data_transfer mismatch") - } - if actual.DataTransferLimits[idx].DownloadDataTransfer != l.DownloadDataTransfer { - return errors.New("data transfer limit download_data_transfer mismatch") - } - if actual.DataTransferLimits[idx].TotalDataTransfer != l.TotalDataTransfer { - return errors.New("data transfer limit total_data_transfer mismatch") - } - for _, source := range actual.DataTransferLimits[idx].Sources { - if !util.Contains(l.Sources, source) { - return errors.New("data transfer limit source mismatch") - } - } - } - - return nil -} - func compareUserBandwidthLimitFilters(expected sdk.BaseUserFilters, actual sdk.BaseUserFilters) error { if len(expected.BandwidthLimits) != len(actual.BandwidthLimits) { return errors.New("bandwidth limits filters mismatch") diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml index 7411ccd9..648be26c 100644 --- a/openapi/openapi.yaml +++ b/openapi/openapi.yaml @@ -5455,23 +5455,6 @@ components: type: integer format: int32 description: 'Maximum download bandwidth as KB/s, 0 means unlimited' - DataTransferLimit: - type: object - properties: - sources: - type: array - items: - type: string - description: 'Source networks in CIDR notation as defined in RFC 4632 and RFC 4291 for example `192.0.2.0/24` or `2001:db8::/32`. The limit applies if the defined networks contain the client IP' - upload_data_transfer: - type: integer - description: 'Maximum data transfer allowed for uploads as MB. 0 means no limit' - download_data_transfer: - type: integer - description: 'Maximum data transfer allowed for downloads as MB. 0 means no limit' - total_data_transfer: - type: integer - description: 'Maximum total data transfer as MB. 0 means unlimited. You can set a total data transfer instead of the individual values for uploads and downloads' BaseUserFilters: type: object properties: @@ -5532,10 +5515,6 @@ components: type: array items: $ref: '#/components/schemas/BandwidthLimit' - data_transfer_limits: - type: array - items: - $ref: '#/components/schemas/DataTransferLimit' external_auth_cache_time: type: integer description: 'Defines the cache time, in seconds, for users authenticated using an external auth hook. 0 means no cache' diff --git a/templates/webadmin/group.html b/templates/webadmin/group.html index bd29388f..2a5e6cbb 100644 --- a/templates/webadmin/group.html +++ b/templates/webadmin/group.html @@ -554,105 +554,6 @@ along with this program. If not, see . -
-
- Per-source data transfer limits -
-
-
-
- {{range $idx, $dtLimit := .Group.UserSettings.Filters.DataTransferLimits -}} -
-
- - - Comma separated IP/Mask in CIDR format, example: "192.168.1.0/24,10.8.0.100/32" - -
-
-
- - - UL (MB). 0 means no limit - -
-
- - - DL (MB). 0 means no limit - -
-
-
-
- - - Total (MB). 0 means no limit - -
-
-
- -
-
- {{else}} -
-
- - - Comma separated IP/Mask in CIDR format, example: "192.168.1.0/24,10.8.0.100/32" - -
-
-
- - - UL (MB). 0 means no limit - -
-
- - - DL (MB). 0 means no limit - -
-
-
-
- - - Total (MB). 0 means no limit - -
-
-
- -
-
- {{end}} -
-
- -
- -
-
-
- diff --git a/templates/webadmin/sharedcomponents.html b/templates/webadmin/sharedcomponents.html index 9c473f39..aef41135 100644 --- a/templates/webadmin/sharedcomponents.html +++ b/templates/webadmin/sharedcomponents.html @@ -137,58 +137,6 @@ along with this program. If not, see . $(this).closest(".form_field_bwlimits_outer_row").remove(); }); - $("body").on("click", ".add_new_dtlimit_field_btn", function () { - let index = $(".form_field_dtlimits_outer").find(".form_field_dtlimits_outer_row").length; - while (document.getElementById("idDataTransferLimitSources"+index) != null){ - index++; - } - $(".form_field_dtlimits_outer").append(` -
-
- - - Comma separated IP/Mask in CIDR format, example: "192.168.1.0/24,10.8.0.100/32" - -
-
-
- - - UL (MB). 0 means no limit - -
-
- - - DL (MB). 0 means no limit - -
-
-
-
- - - Total (MB). 0 means no limit - -
-
-
- -
-
- `); - }); - - $("body").on("click", ".remove_dtlimit_btn_frm_field", function () { - $(this).closest(".form_field_dtlimits_outer_row").remove(); - }); - $("body").on("click", ".add_new_pattern_field_btn", function () { let index = $(".form_field_patterns_outer").find(".form_field_patterns_outer_row").length; while (document.getElementById("idPatternPath"+index) != null){ diff --git a/templates/webadmin/user.html b/templates/webadmin/user.html index a37e9ca7..1c5d2a4c 100644 --- a/templates/webadmin/user.html +++ b/templates/webadmin/user.html @@ -834,105 +834,6 @@ along with this program. If not, see . -
-
- Per-source data transfer limits -
-
-
-
- {{range $idx, $dtLimit := .User.Filters.DataTransferLimits -}} -
-
- - - Comma separated IP/Mask in CIDR format, example: "192.168.1.0/24,10.8.0.100/32" - -
-
-
- - - UL (MB). 0 means no limit - -
-
- - - DL (MB). 0 means no limit - -
-
-
-
- - - Total (MB). 0 means no limit - -
-
-
- -
-
- {{else}} -
-
- - - Comma separated IP/Mask in CIDR format, example: "192.168.1.0/24,10.8.0.100/32" - -
-
-
- - - UL (MB). 0 means no limit - -
-
- - - DL (MB). 0 means no limit - -
-
-
-
- - - Total (MB). 0 means no limit - -
-
-
- -
-
- {{end}} -
-
- -
- -
-
-
- diff --git a/templates/webclient/files.html b/templates/webclient/files.html index 99c4c601..b7d733c8 100644 --- a/templates/webclient/files.html +++ b/templates/webclient/files.html @@ -34,6 +34,82 @@ along with this program. If not, see . {{end}} +{{define "additionalnavitems"}} +{{if .QuotaUsage.HasQuotaInfo}} + + +
+{{end}} +{{end}} + {{define "page_body"}}