WebAdmin: allow to disable 2FA
Before it was only possible using REST API Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
76ffa107dd
commit
a577d8b3cd
17 changed files with 312 additions and 129 deletions
30
go.mod
30
go.mod
|
@ -10,14 +10,14 @@ require (
|
||||||
github.com/alexedwards/argon2id v1.0.0
|
github.com/alexedwards/argon2id v1.0.0
|
||||||
github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964
|
github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964
|
||||||
github.com/aws/aws-sdk-go-v2 v1.25.1
|
github.com/aws/aws-sdk-go-v2 v1.25.1
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.27.2
|
github.com/aws/aws-sdk-go-v2/config v1.27.3
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.2
|
github.com/aws/aws-sdk-go-v2/credentials v1.17.3
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.4
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.5
|
||||||
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.20.3
|
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.21.0
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.50.3
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.51.0
|
||||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.27.3
|
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.0
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.27.2
|
github.com/aws/aws-sdk-go-v2/service/sts v1.28.0
|
||||||
github.com/bmatcuk/doublestar/v4 v4.6.1
|
github.com/bmatcuk/doublestar/v4 v4.6.1
|
||||||
github.com/cockroachdb/cockroach-go/v2 v2.3.6
|
github.com/cockroachdb/cockroach-go/v2 v2.3.6
|
||||||
github.com/coreos/go-oidc/v3 v3.9.0
|
github.com/coreos/go-oidc/v3 v3.9.0
|
||||||
|
@ -74,7 +74,7 @@ require (
|
||||||
golang.org/x/sys v0.17.0
|
golang.org/x/sys v0.17.0
|
||||||
golang.org/x/term v0.17.0
|
golang.org/x/term v0.17.0
|
||||||
golang.org/x/time v0.5.0
|
golang.org/x/time v0.5.0
|
||||||
google.golang.org/api v0.166.0
|
google.golang.org/api v0.167.0
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -94,8 +94,8 @@ require (
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.1 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.1 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.19.2 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sso v1.20.0 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.2 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.0 // indirect
|
||||||
github.com/aws/smithy-go v1.20.1 // indirect
|
github.com/aws/smithy-go v1.20.1 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/boombuler/barcode v1.0.1 // indirect
|
github.com/boombuler/barcode v1.0.1 // indirect
|
||||||
|
@ -146,7 +146,7 @@ require (
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||||
github.com/prometheus/client_model v0.6.0 // indirect
|
github.com/prometheus/client_model v0.6.0 // indirect
|
||||||
github.com/prometheus/common v0.47.0 // indirect
|
github.com/prometheus/common v0.48.0 // indirect
|
||||||
github.com/prometheus/procfs v0.12.0 // indirect
|
github.com/prometheus/procfs v0.12.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||||
|
@ -162,11 +162,11 @@ require (
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.23.1 // indirect
|
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.23.1 // indirect
|
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.23.1 // indirect
|
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect
|
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
|
||||||
golang.org/x/mod v0.15.0 // indirect
|
golang.org/x/mod v0.15.0 // indirect
|
||||||
golang.org/x/sync v0.6.0 // indirect
|
golang.org/x/sync v0.6.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
|
|
60
go.sum
60
go.sum
|
@ -37,14 +37,14 @@ github.com/aws/aws-sdk-go-v2 v1.25.1 h1:P7hU6A5qEdmajGwvae/zDkOq+ULLC9tQBTwqqiwF
|
||||||
github.com/aws/aws-sdk-go-v2 v1.25.1/go.mod h1:Evoc5AsmtveRt1komDwIsjHFyrP5tDuF1D1U+6z6pNo=
|
github.com/aws/aws-sdk-go-v2 v1.25.1/go.mod h1:Evoc5AsmtveRt1komDwIsjHFyrP5tDuF1D1U+6z6pNo=
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 h1:gTK2uhtAPtFcdRRJilZPx8uJLL2J85xK11nKtWL0wfU=
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 h1:gTK2uhtAPtFcdRRJilZPx8uJLL2J85xK11nKtWL0wfU=
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1/go.mod h1:sxpLb+nZk7tIfCWChfd+h4QwHNUR57d8hA1cleTkjJo=
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1/go.mod h1:sxpLb+nZk7tIfCWChfd+h4QwHNUR57d8hA1cleTkjJo=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.27.2 h1:XnMKB9JRjfnxg9ZkUic4MiapnWJISWRo8HVM+7nx9qQ=
|
github.com/aws/aws-sdk-go-v2/config v1.27.3 h1:0PRdb/q5a77HVYj+2rvPiCObfMfl/pWhwa5cs3cnl3c=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.27.2/go.mod h1:z/XIktFoVIKNEqX/811vx4eHetrC3tAkgJKL1ZY/KM4=
|
github.com/aws/aws-sdk-go-v2/config v1.27.3/go.mod h1:WeRAr9ENap9NAegbfNsLqGQd8ERz5ypdIUx4j0/ZgKI=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.2 h1:tCZXWtH0HiIEZ50NJ7/QEaXmuzEd36L+2JUiZkp2nsc=
|
github.com/aws/aws-sdk-go-v2/credentials v1.17.3 h1:dDM5wrgwOL5gTZ0Gv/bvewPldjBcJywoaO5ClERrOGE=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.2/go.mod h1:7Zo+D6q4auSIo3p4EItuTKTk7J+RqjASISZqLvmUgpc=
|
github.com/aws/aws-sdk-go-v2/credentials v1.17.3/go.mod h1:G96Nuaw9qJS+s3OnK8RW8VEKEOjXi8H5Jk4lC/ZyZbw=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1 h1:lk1ZZFbdb24qpOwVC1AwYNrswUjAxeyey6kFBVANudQ=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1 h1:lk1ZZFbdb24qpOwVC1AwYNrswUjAxeyey6kFBVANudQ=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1/go.mod h1:/xJ6x1NehNGCX4tvGzzj2bq5TBOT/Yxq+qbL9Jpx2Vk=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1/go.mod h1:/xJ6x1NehNGCX4tvGzzj2bq5TBOT/Yxq+qbL9Jpx2Vk=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.4 h1:yuhSpqtahkrC8kRCU5v4gEaTDy/ccTIPIkufIRF7YTk=
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.5 h1:IEv6homMJMnedG/2VWfNuV34ouXUmK8E7y4rAl59Fhs=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.4/go.mod h1:q3SxgP2WD9YRLCybtyse8EgO3vKKWVmxlTmBNeRXPyk=
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.5/go.mod h1:a+wq9mSuG13iSkVMR1O8VApmAISm1ca+E2RQpcB3flw=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.1 h1:evvi7FbTAoFxdP/mixmP7LIYzQWAmzBcwNB/es9XPNc=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.1 h1:evvi7FbTAoFxdP/mixmP7LIYzQWAmzBcwNB/es9XPNc=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.1/go.mod h1:rH61DT6FDdikhPghymripNUCsf+uVF4Cnk4c4DBKH64=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.1/go.mod h1:rH61DT6FDdikhPghymripNUCsf+uVF4Cnk4c4DBKH64=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.1 h1:RAnaIrbxPtlXNVI/OIlh1sidTQ3e1qM6LRjs7N0bE0I=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.1 h1:RAnaIrbxPtlXNVI/OIlh1sidTQ3e1qM6LRjs7N0bE0I=
|
||||||
|
@ -61,18 +61,18 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1 h1:cVP8mng1R
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1/go.mod h1:C8sQjoyAsdfjC7hpy4+S6B92hnFzx0d0UAyHicaOTIE=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1/go.mod h1:C8sQjoyAsdfjC7hpy4+S6B92hnFzx0d0UAyHicaOTIE=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.1 h1:OYmmIcyw19f7x0qLBLQ3XsrCZSSyLhxd9GXng5evsN4=
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.1 h1:OYmmIcyw19f7x0qLBLQ3XsrCZSSyLhxd9GXng5evsN4=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.1/go.mod h1:s5rqdn74Vdg10k61Pwf4ZHEApOSD6CKRe6qpeHDq32I=
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.1/go.mod h1:s5rqdn74Vdg10k61Pwf4ZHEApOSD6CKRe6qpeHDq32I=
|
||||||
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.20.3 h1:uOHZ8HCjUHrRUi+sezA1yCeJVwa4Yy91tZDrWn1sT8w=
|
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.21.0 h1:NEWfVJgrDwEXrKDNrrX+2LtWhKVLYpJ2d7/gr1N1B54=
|
||||||
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.20.3/go.mod h1:TzgisXFoXgCssgP11SzC6KrvcyCErz5c3w++m3xFOfo=
|
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.21.0/go.mod h1:TzgisXFoXgCssgP11SzC6KrvcyCErz5c3w++m3xFOfo=
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.50.3 h1:Cv/HH7sLzEdJMYQi4MCNHxZeyubQNOOIdVc0VU0lo3Q=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.51.0 h1:rNVsCe3bqTAhG+qjnHJKgYKdHEsqqo/GMK3gEYY8W6g=
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.50.3/go.mod h1:lTW7O4iMAnO2o7H3XJTvqaWFZCH6zIPs+eP7RdG/yp0=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.51.0/go.mod h1:lTW7O4iMAnO2o7H3XJTvqaWFZCH6zIPs+eP7RdG/yp0=
|
||||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.27.3 h1:LP38dk6XSNKyWAr3ZNEVECBPjEnoP+/SGvOfX0tRy+U=
|
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.0 h1:Xf3s55N9cqKvFK6D70zCXvXXN4ZovTCy7glL+gUhLEc=
|
||||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.27.3/go.mod h1:RA3ERghFSivbTf0Sbsxv/grUuLMcyAjm0F/PylJMmEs=
|
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.0/go.mod h1:RA3ERghFSivbTf0Sbsxv/grUuLMcyAjm0F/PylJMmEs=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.19.2 h1:pnj8llQoBAHD4UmbM8UM5GdfycFJKMhgPSeaOyRaZ34=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.20.0 h1:6YL8G91QZ52KlPrLkEgEez5kejIVwChVCgND3qgY5j0=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.19.2/go.mod h1:x6/tCd1o/AOKQR+iYnjrzhJxD+w0xRN34asGPaSV7ew=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.20.0/go.mod h1:x6/tCd1o/AOKQR+iYnjrzhJxD+w0xRN34asGPaSV7ew=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.2 h1:L4yhKxW6HbTSQ08OsvPJuaspaLE40qMgprgXUNFUiMg=
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.0 h1:+DqIa5Ll7W311QLUvGFDdVit9uC4G0VioDdw08cXcow=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.2/go.mod h1:lZB123q0SVQ3dfIbEOcGzhQHrwVBcHVReNS9tm20oU4=
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.0/go.mod h1:lZB123q0SVQ3dfIbEOcGzhQHrwVBcHVReNS9tm20oU4=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.27.2 h1:Dr+7r/p20XpN+1U5tVNZfA2bLq0kQ9IjVBM0iAyMMLg=
|
github.com/aws/aws-sdk-go-v2/service/sts v1.28.0 h1:F7tQr61zYnTaeY50Rn4jwfVQbtcqJuBRwN/nGGNwzb0=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.27.2/go.mod h1:ozhhG9/NB5c9jcmhGq6tX9dpp21LYdmRWRQVppASim4=
|
github.com/aws/aws-sdk-go-v2/service/sts v1.28.0/go.mod h1:ozhhG9/NB5c9jcmhGq6tX9dpp21LYdmRWRQVppASim4=
|
||||||
github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw=
|
github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw=
|
||||||
github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
|
github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
|
@ -333,8 +333,8 @@ github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlk
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos=
|
github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos=
|
||||||
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
|
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
|
||||||
github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k=
|
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
|
||||||
github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
|
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
|
||||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
|
@ -419,14 +419,14 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.4
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0/go.mod h1:tIKj3DbO8N9Y2xo52og3irLsPI4GW02DSMtrVgNMgxg=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0/go.mod h1:tIKj3DbO8N9Y2xo52og3irLsPI4GW02DSMtrVgNMgxg=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 h1:doUP+ExOpH3spVTLS0FcWGLnQrPct/hD/bCPbDRUEAU=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 h1:doUP+ExOpH3spVTLS0FcWGLnQrPct/hD/bCPbDRUEAU=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0/go.mod h1:rdENBZMT2OE6Ne/KLwpiXudnAsbdrdBaqBvTN8M8BgA=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0/go.mod h1:rdENBZMT2OE6Ne/KLwpiXudnAsbdrdBaqBvTN8M8BgA=
|
||||||
go.opentelemetry.io/otel v1.23.1 h1:Za4UzOqJYS+MUczKI320AtqZHZb7EqxO00jAHE0jmQY=
|
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||||
go.opentelemetry.io/otel v1.23.1/go.mod h1:Td0134eafDLcTS4y+zQ26GE8u3dEuRBiBCTUIRHaikA=
|
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||||
go.opentelemetry.io/otel/metric v1.23.1 h1:PQJmqJ9u2QaJLBOELl1cxIdPcpbwzbkjfEyelTl2rlo=
|
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||||
go.opentelemetry.io/otel/metric v1.23.1/go.mod h1:mpG2QPlAfnK8yNhNJAxDZruU9Y1/HubbC+KyH8FaCWI=
|
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||||
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
|
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
|
||||||
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
|
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
|
||||||
go.opentelemetry.io/otel/trace v1.23.1 h1:4LrmmEd8AU2rFvU1zegmvqW7+kWarxtNOPyeL6HmYY8=
|
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||||
go.opentelemetry.io/otel/trace v1.23.1/go.mod h1:4IpnpJFwr1mo/6HL8XIPJaE9y0+u1KcVmuW7dwFSVrI=
|
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||||
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
|
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
|
||||||
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
||||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
|
@ -434,8 +434,8 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8
|
||||||
gocloud.dev v0.36.0 h1:q5zoXux4xkOZP473e1EZbG8Gq9f0vlg1VNH5Du/ybus=
|
gocloud.dev v0.36.0 h1:q5zoXux4xkOZP473e1EZbG8Gq9f0vlg1VNH5Du/ybus=
|
||||||
gocloud.dev v0.36.0/go.mod h1:bLxah6JQVKBaIxzsr5BQLYB4IYdWHkMZdzCXlo6F0gg=
|
gocloud.dev v0.36.0/go.mod h1:bLxah6JQVKBaIxzsr5BQLYB4IYdWHkMZdzCXlo6F0gg=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE=
|
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
|
||||||
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
|
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
@ -529,8 +529,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
|
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
|
||||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||||
google.golang.org/api v0.166.0 h1:6m4NUwrZYhAaVIHZWxaKjw1L1vNAjtMwORmKRyEEo24=
|
google.golang.org/api v0.167.0 h1:CKHrQD1BLRii6xdkatBDXyKzM0mkawt2QP+H3LtPmSE=
|
||||||
google.golang.org/api v0.166.0/go.mod h1:4FcBc686KFi7QI/U51/2GKKevfZMpM17sCdibqe/bSA=
|
google.golang.org/api v0.167.0/go.mod h1:4FcBc686KFi7QI/U51/2GKKevfZMpM17sCdibqe/bSA=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
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.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||||
|
|
|
@ -58,6 +58,7 @@ const (
|
||||||
PermAdminManageEventRules = "manage_event_rules"
|
PermAdminManageEventRules = "manage_event_rules"
|
||||||
PermAdminManageRoles = "manage_roles"
|
PermAdminManageRoles = "manage_roles"
|
||||||
PermAdminManageIPLists = "manage_ip_lists"
|
PermAdminManageIPLists = "manage_ip_lists"
|
||||||
|
PermAdminDisableMFA = "disable_mfa"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -75,7 +76,7 @@ var (
|
||||||
PermAdminCloseConnections, PermAdminViewServerStatus, PermAdminManageAdmins, PermAdminManageRoles,
|
PermAdminCloseConnections, PermAdminViewServerStatus, PermAdminManageAdmins, PermAdminManageRoles,
|
||||||
PermAdminManageEventRules, PermAdminManageAPIKeys, PermAdminQuotaScans, PermAdminManageSystem,
|
PermAdminManageEventRules, PermAdminManageAPIKeys, PermAdminQuotaScans, PermAdminManageSystem,
|
||||||
PermAdminManageDefender, PermAdminViewDefender, PermAdminManageIPLists, PermAdminRetentionChecks,
|
PermAdminManageDefender, PermAdminViewDefender, PermAdminManageIPLists, PermAdminRetentionChecks,
|
||||||
PermAdminViewEvents}
|
PermAdminViewEvents, PermAdminDisableMFA}
|
||||||
forbiddenPermsForRoleAdmins = []string{PermAdminAny, PermAdminManageAdmins, PermAdminManageSystem,
|
forbiddenPermsForRoleAdmins = []string{PermAdminAny, PermAdminManageAdmins, PermAdminManageSystem,
|
||||||
PermAdminManageEventRules, PermAdminManageIPLists, PermAdminManageRoles}
|
PermAdminManageEventRules, PermAdminManageIPLists, PermAdminManageRoles}
|
||||||
)
|
)
|
||||||
|
|
|
@ -100,6 +100,10 @@ func disableAdmin2FA(w http.ResponseWriter, r *http.Request) {
|
||||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if !admin.Filters.TOTPConfig.Enabled {
|
||||||
|
sendAPIResponse(w, r, nil, "two-factor authentication is not enabled", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
if admin.Username == claims.Username {
|
if admin.Username == claims.Username {
|
||||||
if admin.Filters.RequireTwoFactor {
|
if admin.Filters.RequireTwoFactor {
|
||||||
err := util.NewValidationError("two-factor authentication must be enabled")
|
err := util.NewValidationError("two-factor authentication must be enabled")
|
||||||
|
|
|
@ -134,6 +134,10 @@ func disableUser2FA(w http.ResponseWriter, r *http.Request) {
|
||||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if !user.Filters.TOTPConfig.Enabled {
|
||||||
|
sendAPIResponse(w, r, nil, "two-factor authentication is not enabled", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
user.Filters.RecoveryCodes = nil
|
user.Filters.RecoveryCodes = nil
|
||||||
user.Filters.TOTPConfig = dataprovider.UserTOTPConfig{
|
user.Filters.TOTPConfig = dataprovider.UserTOTPConfig{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
|
|
|
@ -6812,14 +6812,6 @@ func TestNamingRules(t *testing.T) {
|
||||||
rr = executeRequest(req)
|
rr = executeRequest(req)
|
||||||
checkResponseCode(t, http.StatusBadRequest, rr)
|
checkResponseCode(t, http.StatusBadRequest, rr)
|
||||||
assert.Contains(t, rr.Body.String(), "the following characters are allowed")
|
assert.Contains(t, rr.Body.String(), "the following characters are allowed")
|
||||||
|
|
||||||
req, err = http.NewRequest(http.MethodPut, adminPath+"/"+admin.Username+"/2fa/disable", nil)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
setBearerForReq(req, adminAPIToken)
|
|
||||||
rr = executeRequest(req)
|
|
||||||
checkResponseCode(t, http.StatusBadRequest, rr)
|
|
||||||
assert.Contains(t, rr.Body.String(), "the following characters are allowed")
|
|
||||||
|
|
||||||
// test admin reset password
|
// test admin reset password
|
||||||
form = make(url.Values)
|
form = make(url.Values)
|
||||||
form.Set("username", admin.Username)
|
form.Set("username", admin.Username)
|
||||||
|
@ -9086,6 +9078,18 @@ func TestAdminTwoFactorLogin(t *testing.T) {
|
||||||
admin.Password = altAdminPassword
|
admin.Password = altAdminPassword
|
||||||
admin, _, err := httpdtest.AddAdmin(admin, http.StatusCreated)
|
admin, _, err := httpdtest.AddAdmin(admin, http.StatusCreated)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
admin1 := getTestAdmin()
|
||||||
|
admin1.Username = altAdminUsername + "1"
|
||||||
|
admin1.Password = altAdminPassword
|
||||||
|
var permissions []string
|
||||||
|
for _, p := range admin1.GetValidPerms() {
|
||||||
|
if p != dataprovider.PermAdminAny && p != dataprovider.PermAdminDisableMFA {
|
||||||
|
permissions = append(permissions, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
admin1.Permissions = permissions
|
||||||
|
admin1, _, err = httpdtest.AddAdmin(admin1, http.StatusCreated)
|
||||||
|
assert.NoError(t, err)
|
||||||
// enable two factor authentication
|
// enable two factor authentication
|
||||||
configName, key, _, err := mfa.GenerateTOTPSecret(mfa.GetAvailableTOTPConfigNames()[0], admin.Username)
|
configName, key, _, err := mfa.GenerateTOTPSecret(mfa.GetAvailableTOTPConfigNames()[0], admin.Username)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -9369,12 +9373,27 @@ func TestAdminTwoFactorLogin(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// disable TOTP
|
// disable TOTP
|
||||||
|
altToken1, err := getJWTAPITokenFromTestServer(admin1.Username, altAdminPassword)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
req, err = http.NewRequest(http.MethodPut, adminPath+"/"+altAdminUsername+"/2fa/disable", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
setBearerForReq(req, altToken1)
|
||||||
|
rr = executeRequest(req)
|
||||||
|
checkResponseCode(t, http.StatusForbidden, rr)
|
||||||
|
|
||||||
req, err = http.NewRequest(http.MethodPut, adminPath+"/"+altAdminUsername+"/2fa/disable", nil)
|
req, err = http.NewRequest(http.MethodPut, adminPath+"/"+altAdminUsername+"/2fa/disable", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
setBearerForReq(req, altToken)
|
setBearerForReq(req, altToken)
|
||||||
rr = executeRequest(req)
|
rr = executeRequest(req)
|
||||||
checkResponseCode(t, http.StatusOK, rr)
|
checkResponseCode(t, http.StatusOK, rr)
|
||||||
|
|
||||||
|
req, err = http.NewRequest(http.MethodPut, adminPath+"/"+altAdminUsername+"/2fa/disable", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
setBearerForReq(req, altToken)
|
||||||
|
rr = executeRequest(req)
|
||||||
|
checkResponseCode(t, http.StatusBadRequest, rr)
|
||||||
|
assert.Contains(t, rr.Body.String(), "two-factor authentication is not enabled")
|
||||||
|
|
||||||
form = make(url.Values)
|
form = make(url.Values)
|
||||||
form.Set("recovery_code", recoveryCode)
|
form.Set("recovery_code", recoveryCode)
|
||||||
form.Set(csrfFormToken, csrfToken)
|
form.Set(csrfFormToken, csrfToken)
|
||||||
|
@ -9399,6 +9418,8 @@ func TestAdminTwoFactorLogin(t *testing.T) {
|
||||||
|
|
||||||
_, err = httpdtest.RemoveAdmin(admin, http.StatusOK)
|
_, err = httpdtest.RemoveAdmin(admin, http.StatusOK)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
_, err = httpdtest.RemoveAdmin(admin1, http.StatusOK)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
req, err = http.NewRequest(http.MethodPost, webAdminTwoFactorRecoveryPath, bytes.NewBuffer([]byte(form.Encode())))
|
req, err = http.NewRequest(http.MethodPost, webAdminTwoFactorRecoveryPath, bytes.NewBuffer([]byte(form.Encode())))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -10107,6 +10128,13 @@ func TestWebUserTwoFactorLogin(t *testing.T) {
|
||||||
rr = executeRequest(req)
|
rr = executeRequest(req)
|
||||||
checkResponseCode(t, http.StatusOK, rr)
|
checkResponseCode(t, http.StatusOK, rr)
|
||||||
|
|
||||||
|
req, err = http.NewRequest(http.MethodPut, userPath+"/"+user.Username+"/2fa/disable", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
setBearerForReq(req, adminToken)
|
||||||
|
rr = executeRequest(req)
|
||||||
|
checkResponseCode(t, http.StatusBadRequest, rr)
|
||||||
|
assert.Contains(t, rr.Body.String(), "two-factor authentication is not enabled")
|
||||||
|
|
||||||
form = make(url.Values)
|
form = make(url.Values)
|
||||||
form.Set("recovery_code", recoveryCode)
|
form.Set("recovery_code", recoveryCode)
|
||||||
form.Set("passcode", passcode)
|
form.Set("passcode", passcode)
|
||||||
|
|
|
@ -1364,7 +1364,7 @@ func (s *httpdServer) initializeRouter() {
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminViewUsers)).Get(userPath+"/{username}", getUserByUsername) //nolint:goconst
|
router.With(s.checkPerm(dataprovider.PermAdminViewUsers)).Get(userPath+"/{username}", getUserByUsername) //nolint:goconst
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers)).Put(userPath+"/{username}", updateUser)
|
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers)).Put(userPath+"/{username}", updateUser)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminDeleteUsers)).Delete(userPath+"/{username}", deleteUser)
|
router.With(s.checkPerm(dataprovider.PermAdminDeleteUsers)).Delete(userPath+"/{username}", deleteUser)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers)).Put(userPath+"/{username}/2fa/disable", disableUser2FA)
|
router.With(s.checkPerm(dataprovider.PermAdminDisableMFA)).Put(userPath+"/{username}/2fa/disable", disableUser2FA) //nolint:goconst
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders)).Get(folderPath, getFolders)
|
router.With(s.checkPerm(dataprovider.PermAdminManageFolders)).Get(folderPath, getFolders)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders)).Get(folderPath+"/{name}", getFolderByName) //nolint:goconst
|
router.With(s.checkPerm(dataprovider.PermAdminManageFolders)).Get(folderPath+"/{name}", getFolderByName) //nolint:goconst
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders)).Post(folderPath, addFolder)
|
router.With(s.checkPerm(dataprovider.PermAdminManageFolders)).Post(folderPath, addFolder)
|
||||||
|
@ -1392,7 +1392,7 @@ func (s *httpdServer) initializeRouter() {
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminManageAdmins)).Get(adminPath+"/{username}", getAdminByUsername)
|
router.With(s.checkPerm(dataprovider.PermAdminManageAdmins)).Get(adminPath+"/{username}", getAdminByUsername)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminManageAdmins)).Put(adminPath+"/{username}", updateAdmin)
|
router.With(s.checkPerm(dataprovider.PermAdminManageAdmins)).Put(adminPath+"/{username}", updateAdmin)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminManageAdmins)).Delete(adminPath+"/{username}", deleteAdmin)
|
router.With(s.checkPerm(dataprovider.PermAdminManageAdmins)).Delete(adminPath+"/{username}", deleteAdmin)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminManageAdmins)).Put(adminPath+"/{username}/2fa/disable", disableAdmin2FA)
|
router.With(s.checkPerm(dataprovider.PermAdminDisableMFA)).Put(adminPath+"/{username}/2fa/disable", disableAdmin2FA)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminRetentionChecks)).Get(retentionChecksPath, getRetentionChecks)
|
router.With(s.checkPerm(dataprovider.PermAdminRetentionChecks)).Get(retentionChecksPath, getRetentionChecks)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminRetentionChecks)).Post(retentionBasePath+"/{username}/check",
|
router.With(s.checkPerm(dataprovider.PermAdminRetentionChecks)).Post(retentionBasePath+"/{username}/check",
|
||||||
startRetentionCheck)
|
startRetentionCheck)
|
||||||
|
@ -1752,6 +1752,8 @@ func (s *httpdServer) setupWebAdminRoutes() {
|
||||||
s.handleWebUpdateAdminPost)
|
s.handleWebUpdateAdminPost)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminManageAdmins), verifyCSRFHeader).
|
router.With(s.checkPerm(dataprovider.PermAdminManageAdmins), verifyCSRFHeader).
|
||||||
Delete(webAdminPath+"/{username}", deleteAdmin)
|
Delete(webAdminPath+"/{username}", deleteAdmin)
|
||||||
|
router.With(s.checkPerm(dataprovider.PermAdminDisableMFA), verifyCSRFHeader).
|
||||||
|
Put(webAdminPath+"/{username}/2fa/disable", disableAdmin2FA)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminCloseConnections), verifyCSRFHeader).
|
router.With(s.checkPerm(dataprovider.PermAdminCloseConnections), verifyCSRFHeader).
|
||||||
Delete(webConnectionsPath+"/{connectionID}", handleCloseConnection)
|
Delete(webConnectionsPath+"/{connectionID}", handleCloseConnection)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders), s.refreshCookie).
|
router.With(s.checkPerm(dataprovider.PermAdminManageFolders), s.refreshCookie).
|
||||||
|
@ -1764,6 +1766,8 @@ func (s *httpdServer) setupWebAdminRoutes() {
|
||||||
Post(webScanVFolderPath+"/{name}", startFolderQuotaScan)
|
Post(webScanVFolderPath+"/{name}", startFolderQuotaScan)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminDeleteUsers), verifyCSRFHeader).
|
router.With(s.checkPerm(dataprovider.PermAdminDeleteUsers), verifyCSRFHeader).
|
||||||
Delete(webUserPath+"/{username}", deleteUser)
|
Delete(webUserPath+"/{username}", deleteUser)
|
||||||
|
router.With(s.checkPerm(dataprovider.PermAdminDisableMFA), verifyCSRFHeader).
|
||||||
|
Put(webUserPath+"/{username}/2fa/disable", disableUser2FA)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminQuotaScans), verifyCSRFHeader).
|
router.With(s.checkPerm(dataprovider.PermAdminQuotaScans), verifyCSRFHeader).
|
||||||
Post(webQuotaScanPath+"/{username}", startUserQuotaScan)
|
Post(webQuotaScanPath+"/{username}", startUserQuotaScan)
|
||||||
router.With(s.checkPerm(dataprovider.PermAdminManageSystem)).Get(webMaintenancePath, s.handleWebMaintenance)
|
router.With(s.checkPerm(dataprovider.PermAdminManageSystem)).Get(webMaintenancePath, s.handleWebMaintenance)
|
||||||
|
|
|
@ -4948,6 +4948,7 @@ components:
|
||||||
- manage_event_rules
|
- manage_event_rules
|
||||||
- manage_roles
|
- manage_roles
|
||||||
- manage_ip_lists
|
- manage_ip_lists
|
||||||
|
- disable_mfa
|
||||||
description: |
|
description: |
|
||||||
Admin permissions:
|
Admin permissions:
|
||||||
* `*` - all permissions are granted
|
* `*` - all permissions are granted
|
||||||
|
@ -4971,6 +4972,7 @@ components:
|
||||||
* `manage_event_rules` - manage event actions and rules is allowed
|
* `manage_event_rules` - manage event actions and rules is allowed
|
||||||
* `manage_roles` - manage roles is allowed
|
* `manage_roles` - manage roles is allowed
|
||||||
* `manage_ip_lists` - manage global and ratelimter allow lists and defender block and safe lists is allowed
|
* `manage_ip_lists` - manage global and ratelimter allow lists and defender block and safe lists is allowed
|
||||||
|
* `disable_mfa` - allow to disable two-factor authentication for users and admins
|
||||||
FsProviders:
|
FsProviders:
|
||||||
type: integer
|
type: integer
|
||||||
enum:
|
enum:
|
||||||
|
|
|
@ -132,6 +132,7 @@
|
||||||
"add": "Add",
|
"add": "Add",
|
||||||
"enable": "Enable",
|
"enable": "Enable",
|
||||||
"disable": "Disable",
|
"disable": "Disable",
|
||||||
|
"disable_confirm_btn": "Yes, disable",
|
||||||
"close": "Close",
|
"close": "Close",
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
"configuration": "Configuration",
|
"configuration": "Configuration",
|
||||||
|
@ -403,6 +404,8 @@
|
||||||
"setup_title": "Set up two-factor authentication",
|
"setup_title": "Set up two-factor authentication",
|
||||||
"setup_msg": "Use your preferred Authenticator App (e.g. Microsoft Authenticator, Google Authenticator, Authy, 1Password etc. ) to scan the QR code. It will generate an authentication code for you to enter below.",
|
"setup_msg": "Use your preferred Authenticator App (e.g. Microsoft Authenticator, Google Authenticator, Authy, 1Password etc. ) to scan the QR code. It will generate an authentication code for you to enter below.",
|
||||||
"setup_help": "If you have trouble using the QR code, select manual entry on your app, and enter the code:",
|
"setup_help": "If you have trouble using the QR code, select manual entry on your app, and enter the code:",
|
||||||
|
"disable_msg": "Disable 2FA",
|
||||||
|
"disable_confirm": "Do you want to disable two-factor authentication for the selected user? This action is generally only required if the user has lost access to the second authentication factor",
|
||||||
"disable_question": "Do you want to disable two-factor authentication?",
|
"disable_question": "Do you want to disable two-factor authentication?",
|
||||||
"generate_question": "Do you want to generate a new secret key and invalidate the previous one? Any registered Authenticator App will stop working",
|
"generate_question": "Do you want to generate a new secret key and invalidate the previous one? Any registered Authenticator App will stop working",
|
||||||
"disabled": "Two-factor authentication is disabled",
|
"disabled": "Two-factor authentication is disabled",
|
||||||
|
@ -410,7 +413,7 @@
|
||||||
"recovery_codes_get_err": "Unable to obtain recovery codes",
|
"recovery_codes_get_err": "Unable to obtain recovery codes",
|
||||||
"auth_code_invalid": "Failed to validate the provided authentication code",
|
"auth_code_invalid": "Failed to validate the provided authentication code",
|
||||||
"auth_secret_gen_err": "Failed to generate authentication secret",
|
"auth_secret_gen_err": "Failed to generate authentication secret",
|
||||||
"save_err": "Failed to save configuration",
|
"save_err": "Failed to save two-factor authentication configuration",
|
||||||
"auth_code_required": "The authentication code is required",
|
"auth_code_required": "The authentication code is required",
|
||||||
"no_protocol": "Please select at least a protocol",
|
"no_protocol": "Please select at least a protocol",
|
||||||
"required_protocols": "Unable to disable two-factor authentication. The security policy configured for your account requires two-factor authentication for the following protocols: {{val}}",
|
"required_protocols": "Unable to disable two-factor authentication. The security policy configured for your account requires two-factor authentication for the following protocols: {{val}}",
|
||||||
|
|
|
@ -132,6 +132,7 @@
|
||||||
"add": "Aggiungi",
|
"add": "Aggiungi",
|
||||||
"enable": "Abilita",
|
"enable": "Abilita",
|
||||||
"disable": "Disabilita",
|
"disable": "Disabilita",
|
||||||
|
"disable_confirm_btn": "Si, disabilita",
|
||||||
"close": "Chiudi",
|
"close": "Chiudi",
|
||||||
"search": "Cerca",
|
"search": "Cerca",
|
||||||
"configuration": "Configurazione",
|
"configuration": "Configurazione",
|
||||||
|
@ -403,6 +404,8 @@
|
||||||
"setup_title": "Configura l'autenticazione a due fattori",
|
"setup_title": "Configura l'autenticazione a due fattori",
|
||||||
"setup_msg": "Utilizza la tua app di autenticazione preferita (ad esempio Microsoft Authenticator, Google Authenticator, Authy, 1Password ecc.) per scansionare il codice QR. Verrà generato un codice di autenticazione da inserire di seguito.",
|
"setup_msg": "Utilizza la tua app di autenticazione preferita (ad esempio Microsoft Authenticator, Google Authenticator, Authy, 1Password ecc.) per scansionare il codice QR. Verrà generato un codice di autenticazione da inserire di seguito.",
|
||||||
"setup_help": "Se hai problemi con l'utilizzo del codice QR, seleziona l'inserimento manuale sulla tua app e inserisci il codice:",
|
"setup_help": "Se hai problemi con l'utilizzo del codice QR, seleziona l'inserimento manuale sulla tua app e inserisci il codice:",
|
||||||
|
"disable_msg": "Disabilita 2FA",
|
||||||
|
"disable_confirm": "Vuoi disabilitare l'autenticazione a due fattori per l'utente selezionato? Questa azione è generalmente necessaria solo se l'utente ha perso l'accesso al secondo fattore di autenticazione",
|
||||||
"disable_question": "Vuoi disattivare l'autenticazione a due fattori?",
|
"disable_question": "Vuoi disattivare l'autenticazione a due fattori?",
|
||||||
"generate_question": "Vuoi generare un nuova chiave segreta e invalidare quella precedente? Qualsiasi app di autenticazione registrata smetterà di funzionare",
|
"generate_question": "Vuoi generare un nuova chiave segreta e invalidare quella precedente? Qualsiasi app di autenticazione registrata smetterà di funzionare",
|
||||||
"disabled": "L'autenticazione a due fattori è disabilitata",
|
"disabled": "L'autenticazione a due fattori è disabilitata",
|
||||||
|
@ -410,7 +413,7 @@
|
||||||
"recovery_codes_get_err": "Impossibile ottenere i codici di ripristino",
|
"recovery_codes_get_err": "Impossibile ottenere i codici di ripristino",
|
||||||
"auth_code_invalid": "Impossibile convalidare il codice di autenticazione fornito",
|
"auth_code_invalid": "Impossibile convalidare il codice di autenticazione fornito",
|
||||||
"auth_secret_gen_err": "Impossibile generare il segreto di autenticazione",
|
"auth_secret_gen_err": "Impossibile generare il segreto di autenticazione",
|
||||||
"save_err": "Impossibile salvare la configurazione",
|
"save_err": "Impossibile salvare la configurazione dell'autenticazione a due fattori",
|
||||||
"auth_code_required": "Il codice di autenticazione è obbligatorio",
|
"auth_code_required": "Il codice di autenticazione è obbligatorio",
|
||||||
"no_protocol": "Seleziona almeno un protocollo",
|
"no_protocol": "Seleziona almeno un protocollo",
|
||||||
"required_protocols": "Impossibile disabilitare l'autenticazione a due fattori. La politica di sicurezza configurata per il tuo account richiede l'autenticazione a due fattori per i seguenti protocolli: {{val}}",
|
"required_protocols": "Impossibile disabilitare l'autenticazione a due fattori. La politica di sicurezza configurata per il tuo account richiede l'autenticazione a due fattori per i seguenti protocolli: {{val}}",
|
||||||
|
|
|
@ -175,6 +175,47 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function disableSeconFactorAction(username) {
|
||||||
|
ModalAlert.fire({
|
||||||
|
text: $.t('2fa.disable_confirm'),
|
||||||
|
icon: "warning",
|
||||||
|
confirmButtonText: $.t('general.disable_confirm_btn'),
|
||||||
|
cancelButtonText: $.t('general.cancel'),
|
||||||
|
customClass: {
|
||||||
|
confirmButton: "btn btn-danger",
|
||||||
|
cancelButton: 'btn btn-secondary'
|
||||||
|
}
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed){
|
||||||
|
$('#loading_message').text("");
|
||||||
|
KTApp.showPageLoading();
|
||||||
|
let path = '{{.AdminURL}}' + "/" + encodeURIComponent(username)+"/2fa/disable";
|
||||||
|
|
||||||
|
axios.put(path, null, {
|
||||||
|
timeout: 15000,
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
||||||
|
},
|
||||||
|
validateStatus: function (status) {
|
||||||
|
return status == 200;
|
||||||
|
}
|
||||||
|
}).then(function(response){
|
||||||
|
location.reload();
|
||||||
|
}).catch(function(error){
|
||||||
|
KTApp.hidePageLoading();
|
||||||
|
ModalAlert.fire({
|
||||||
|
text: $.t('2fa.save_err'),
|
||||||
|
icon: "warning",
|
||||||
|
confirmButtonText: $.t('general.ok'),
|
||||||
|
customClass: {
|
||||||
|
confirmButton: "btn btn-primary"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var datatable = function(){
|
var datatable = function(){
|
||||||
var dt;
|
var dt;
|
||||||
|
|
||||||
|
@ -273,17 +314,17 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
data: "filters.totp_config.enabled",
|
data: "filters.totp_config",
|
||||||
visible: false,
|
visible: false,
|
||||||
defaultContent: false,
|
defaultContent: false,
|
||||||
render: function(data, type, row) {
|
render: function(data, type, row) {
|
||||||
if (type === 'display') {
|
if (type === 'display') {
|
||||||
if (data){
|
if (data && data.enabled){
|
||||||
return $.t('general.active');
|
return $.t('general.active');
|
||||||
}
|
}
|
||||||
return $.t('general.inactive')
|
return $.t('general.inactive')
|
||||||
}
|
}
|
||||||
return data;
|
return data && data.enabled;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -307,20 +348,39 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
className: 'text-end',
|
className: 'text-end',
|
||||||
render: function (data, type, row) {
|
render: function (data, type, row) {
|
||||||
if (type === 'display') {
|
if (type === 'display') {
|
||||||
//{{- if .LoggedUser.HasPermission "manage_admins"}}
|
let numActions = 0;
|
||||||
return `<button class="btn btn-light btn-active-light-primary btn-flex btn-center btn-sm rotate" data-kt-menu-trigger="click" data-kt-menu-placement="bottom-end">
|
let username = "{{.LoggedUser.Username}}";
|
||||||
|
let actions = `<button class="btn btn-light btn-active-light-primary btn-flex btn-center btn-sm rotate" data-kt-menu-trigger="click" data-kt-menu-placement="bottom-end">
|
||||||
<span data-i18n="general.actions" class="fs-6">Actions</span>
|
<span data-i18n="general.actions" class="fs-6">Actions</span>
|
||||||
<i class="ki-duotone ki-down fs-5 ms-1 rotate-180"></i>
|
<i class="ki-duotone ki-down fs-5 ms-1 rotate-180"></i>
|
||||||
</button>
|
</button>
|
||||||
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-700 menu-state-bg-light-primary fw-semibold fs-6 w-200px py-4" data-kt-menu="true">
|
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-700 menu-state-bg-light-primary fw-semibold fs-6 w-200px py-4" data-kt-menu="true">`;
|
||||||
<div class="menu-item px-3">
|
//{{- if .LoggedUser.HasPermission "manage_admins"}}
|
||||||
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
numActions++;
|
||||||
</div>
|
actions+=`<div class="menu-item px-3">
|
||||||
<div class="menu-item px-3">
|
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
||||||
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
</div>`;
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
//{{- end}}
|
//{{- end}}
|
||||||
|
//{{- if .LoggedUser.HasPermission "disable_mfa"}}
|
||||||
|
if (row.filters.totp_config && row.filters.totp_config.enabled && username != row.username){
|
||||||
|
numActions++;
|
||||||
|
actions+=`<div class="menu-item px-3">
|
||||||
|
<a data-i18n="2fa.disable_msg" href="#" class="menu-link text-danger px-3" data-table-action="disable_2fa_row">Disable 2FA</a>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
//{{- end}}
|
||||||
|
//{{- if .LoggedUser.HasPermission "manage_admins"}}
|
||||||
|
if (username != row.username){
|
||||||
|
numActions++;
|
||||||
|
actions+=`<div class="menu-item px-3">
|
||||||
|
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
//{{- end}}
|
||||||
|
if (numActions > 0){
|
||||||
|
actions+=`</div>`;
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -406,6 +466,17 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const diable2FAButtons = document.querySelectorAll('[data-table-action="disable_2fa_row"]');
|
||||||
|
diable2FAButtons.forEach(d => {
|
||||||
|
let el = $(d);
|
||||||
|
el.off("click");
|
||||||
|
el.on("click", function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
let rowData = dt.row(e.target.closest('tr')).data();
|
||||||
|
disableSeconFactorAction(rowData['username']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const deleteButtons = document.querySelectorAll('[data-table-action="delete_row"]');
|
const deleteButtons = document.querySelectorAll('[data-table-action="delete_row"]');
|
||||||
deleteButtons.forEach(d => {
|
deleteButtons.forEach(d => {
|
||||||
let el = $(d);
|
let el = $(d);
|
||||||
|
|
|
@ -230,11 +230,11 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
||||||
</div>`
|
</div>`;
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
||||||
</div>`
|
</div>`;
|
||||||
//{{- end}}
|
//{{- end}}
|
||||||
if (numActions > 0){
|
if (numActions > 0){
|
||||||
actions+=`</div>`;
|
actions+=`</div>`;
|
||||||
|
|
|
@ -286,17 +286,17 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
||||||
</div>`
|
</div>`;
|
||||||
numActions++;
|
numActions++;
|
||||||
if (row.trigger === 6){
|
if (row.trigger === 6){
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="rules.run" href="#" class="menu-link px-3" data-table-action="run_row">Run</a>
|
<a data-i18n="rules.run" href="#" class="menu-link px-3" data-table-action="run_row">Run</a>
|
||||||
</div>`
|
</div>`;
|
||||||
numActions++;
|
numActions++;
|
||||||
}
|
}
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
||||||
</div>`
|
</div>`;
|
||||||
//{{- end}}
|
//{{- end}}
|
||||||
if (numActions > 0){
|
if (numActions > 0){
|
||||||
actions+=`</div>`;
|
actions+=`</div>`;
|
||||||
|
|
|
@ -287,19 +287,19 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
||||||
</div>`
|
</div>`;
|
||||||
//{{- end}}
|
//{{- end}}
|
||||||
//{{- if .LoggedUser.HasPermission "manage_system"}}
|
//{{- if .LoggedUser.HasPermission "manage_system"}}
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.template" href="#" class="menu-link px-3" data-table-action="template_row">Template</a>
|
<a data-i18n="general.template" href="#" class="menu-link px-3" data-table-action="template_row">Template</a>
|
||||||
</div>`
|
</div>`;
|
||||||
//{{- end}}
|
//{{- end}}
|
||||||
//{{- if .LoggedUser.HasPermission "manage_folders"}}
|
//{{- if .LoggedUser.HasPermission "manage_folders"}}
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
||||||
</div>`
|
</div>`;
|
||||||
//{{- end}}
|
//{{- end}}
|
||||||
if (numActions > 0){
|
if (numActions > 0){
|
||||||
actions+=`</div>`;
|
actions+=`</div>`;
|
||||||
|
|
|
@ -228,11 +228,11 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
||||||
</div>`
|
</div>`;
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
||||||
</div>`
|
</div>`;
|
||||||
//{{- end}}
|
//{{- end}}
|
||||||
if (numActions > 0){
|
if (numActions > 0){
|
||||||
actions+=`</div>`;
|
actions+=`</div>`;
|
||||||
|
|
|
@ -229,11 +229,11 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
||||||
</div>`
|
</div>`;
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
||||||
</div>`
|
</div>`;
|
||||||
//{{- end}}
|
//{{- end}}
|
||||||
if (numActions > 0){
|
if (numActions > 0){
|
||||||
actions+=`</div>`;
|
actions+=`</div>`;
|
||||||
|
|
|
@ -188,44 +188,85 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function quotaScanAction(username) {
|
function disableSeconFactorAction(username) {
|
||||||
$('#loading_message').text("");
|
ModalAlert.fire({
|
||||||
KTApp.showPageLoading();
|
text: $.t('2fa.disable_confirm'),
|
||||||
let path = '{{.QuotaScanURL}}' + "/" + encodeURIComponent(username);
|
icon: "warning",
|
||||||
axios.post(path, null, {
|
confirmButtonText: $.t('general.disable_confirm_btn'),
|
||||||
timeout: 15000,
|
cancelButtonText: $.t('general.cancel'),
|
||||||
headers: {
|
customClass: {
|
||||||
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
confirmButton: "btn btn-danger",
|
||||||
},
|
cancelButton: 'btn btn-secondary'
|
||||||
validateStatus: function (status) {
|
}
|
||||||
return status == 202;
|
}).then((result) => {
|
||||||
}
|
if (result.isConfirmed){
|
||||||
}).then(function (response) {
|
$('#loading_message').text("");
|
||||||
KTApp.hidePageLoading();
|
KTApp.showPageLoading();
|
||||||
showToast(1, 'general.quota_scan_started');
|
let path = '{{.UserURL}}' + "/" + encodeURIComponent(username)+"/2fa/disable";
|
||||||
}).catch(function (error) {
|
|
||||||
KTApp.hidePageLoading();
|
axios.put(path, null, {
|
||||||
let errorMessage;
|
timeout: 15000,
|
||||||
if (error && error.response) {
|
headers: {
|
||||||
switch (error.response.status) {
|
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
||||||
case 409:
|
},
|
||||||
errorMessage = "general.quota_scan_conflit";
|
validateStatus: function (status) {
|
||||||
break;
|
return status == 200;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!errorMessage) {
|
|
||||||
errorMessage = "general.quota_scan_error";
|
|
||||||
}
|
|
||||||
ModalAlert.fire({
|
|
||||||
text: $.t(errorMessage),
|
|
||||||
icon: "warning",
|
|
||||||
confirmButtonText: $.t('general.ok'),
|
|
||||||
customClass: {
|
|
||||||
confirmButton: "btn btn-primary"
|
|
||||||
}
|
}
|
||||||
|
}).then(function(response){
|
||||||
|
location.reload();
|
||||||
|
}).catch(function(error){
|
||||||
|
KTApp.hidePageLoading();
|
||||||
|
ModalAlert.fire({
|
||||||
|
text: $.t('2fa.save_err'),
|
||||||
|
icon: "warning",
|
||||||
|
confirmButtonText: $.t('general.ok'),
|
||||||
|
customClass: {
|
||||||
|
confirmButton: "btn btn-primary"
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function quotaScanAction(username) {
|
||||||
|
$('#loading_message').text("");
|
||||||
|
KTApp.showPageLoading();
|
||||||
|
let path = '{{.QuotaScanURL}}' + "/" + encodeURIComponent(username);
|
||||||
|
axios.post(path, null, {
|
||||||
|
timeout: 15000,
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
||||||
|
},
|
||||||
|
validateStatus: function (status) {
|
||||||
|
return status == 202;
|
||||||
|
}
|
||||||
|
}).then(function (response) {
|
||||||
|
KTApp.hidePageLoading();
|
||||||
|
showToast(1, 'general.quota_scan_started');
|
||||||
|
}).catch(function (error) {
|
||||||
|
KTApp.hidePageLoading();
|
||||||
|
let errorMessage;
|
||||||
|
if (error && error.response) {
|
||||||
|
switch (error.response.status) {
|
||||||
|
case 409:
|
||||||
|
errorMessage = "general.quota_scan_conflit";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!errorMessage) {
|
||||||
|
errorMessage = "general.quota_scan_error";
|
||||||
|
}
|
||||||
|
ModalAlert.fire({
|
||||||
|
text: $.t(errorMessage),
|
||||||
|
icon: "warning",
|
||||||
|
confirmButtonText: $.t('general.ok'),
|
||||||
|
customClass: {
|
||||||
|
confirmButton: "btn btn-primary"
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var datatable = function(){
|
var datatable = function(){
|
||||||
var dt;
|
var dt;
|
||||||
|
@ -359,17 +400,20 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
data: "filters.two_factor_protocols",
|
data: "filters.totp_config",
|
||||||
visible: false,
|
visible: false,
|
||||||
defaultContent: "",
|
defaultContent: "",
|
||||||
render: function(data, type, row) {
|
render: function(data, type, row) {
|
||||||
if (type === 'display') {
|
let protocols = "";
|
||||||
if (data){
|
if (data && data.enabled){
|
||||||
return escapeHTML(data.join(', '));
|
protocols = data.protocols.join(', ');
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
return data;
|
if (type === 'display') {
|
||||||
|
if (protocols){
|
||||||
|
return escapeHTML(protocols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return protocols;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -486,25 +530,33 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
<a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
|
||||||
</div>`
|
</div>`;
|
||||||
//{{- end}}
|
//{{- end}}
|
||||||
//{{- if .LoggedUser.HasPermission "manage_system"}}
|
//{{- if .LoggedUser.HasPermission "manage_system"}}
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.template" href="#" class="menu-link px-3" data-table-action="template_row">Template</a>
|
<a data-i18n="general.template" href="#" class="menu-link px-3" data-table-action="template_row">Template</a>
|
||||||
</div>`
|
</div>`;
|
||||||
//{{- end}}
|
//{{- end}}
|
||||||
//{{- if .LoggedUser.HasPermission "quota_scans"}}
|
//{{- if .LoggedUser.HasPermission "quota_scans"}}
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.quota_scan" href="#" class="menu-link px-3" data-table-action="quota_scan_row">Quota scan</a>
|
<a data-i18n="general.quota_scan" href="#" class="menu-link px-3" data-table-action="quota_scan_row">Quota scan</a>
|
||||||
</div>`
|
</div>`;
|
||||||
|
//{{- end}}
|
||||||
|
//{{- if .LoggedUser.HasPermission "disable_mfa"}}
|
||||||
|
if (row.filters.totp_config && row.filters.totp_config.enabled){
|
||||||
|
numActions++;
|
||||||
|
actions+=`<div class="menu-item px-3">
|
||||||
|
<a data-i18n="2fa.disable_msg" href="#" class="menu-link text-danger px-3" data-table-action="disable_2fa_row">Disable 2FA</a>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
//{{- end}}
|
//{{- end}}
|
||||||
//{{- if .LoggedUser.HasPermission "del_users"}}
|
//{{- if .LoggedUser.HasPermission "del_users"}}
|
||||||
numActions++;
|
numActions++;
|
||||||
actions+=`<div class="menu-item px-3">
|
actions+=`<div class="menu-item px-3">
|
||||||
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
<a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
|
||||||
</div>`
|
</div>`;
|
||||||
//{{- end}}
|
//{{- end}}
|
||||||
if (numActions > 0){
|
if (numActions > 0){
|
||||||
actions+=`</div>`;
|
actions+=`</div>`;
|
||||||
|
@ -620,6 +672,17 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const diable2FAButtons = document.querySelectorAll('[data-table-action="disable_2fa_row"]');
|
||||||
|
diable2FAButtons.forEach(d => {
|
||||||
|
let el = $(d);
|
||||||
|
el.off("click");
|
||||||
|
el.on("click", function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
let rowData = dt.row(e.target.closest('tr')).data();
|
||||||
|
disableSeconFactorAction(rowData['username']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const deleteButtons = document.querySelectorAll('[data-table-action="delete_row"]');
|
const deleteButtons = document.querySelectorAll('[data-table-action="delete_row"]');
|
||||||
deleteButtons.forEach(d => {
|
deleteButtons.forEach(d => {
|
||||||
let el = $(d);
|
let el = $(d);
|
||||||
|
|
Loading…
Reference in a new issue