mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-22 07:30:25 +00:00
WIP new WebAdmin: status page
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
eec9c449d4
commit
9fcff83f8f
9 changed files with 260 additions and 155 deletions
6
go.mod
6
go.mod
|
@ -3,7 +3,7 @@ module github.com/drakkan/sftpgo/v2
|
||||||
go 1.21
|
go 1.21
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/storage v1.36.0
|
cloud.google.com/go/storage v1.37.0
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.1
|
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.1
|
||||||
github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5
|
github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5
|
||||||
|
@ -13,9 +13,9 @@ require (
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.26.6
|
github.com/aws/aws-sdk-go-v2/config v1.26.6
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.16
|
github.com/aws/aws-sdk-go-v2/credentials v1.16.16
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.14
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.15
|
||||||
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.19.6
|
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.19.6
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.48.1
|
||||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.2
|
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.2
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7
|
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7
|
||||||
github.com/bmatcuk/doublestar/v4 v4.6.1
|
github.com/bmatcuk/doublestar/v4 v4.6.1
|
||||||
|
|
12
go.sum
12
go.sum
|
@ -9,8 +9,8 @@ cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI=
|
||||||
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
|
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
|
||||||
cloud.google.com/go/kms v1.15.5 h1:pj1sRfut2eRbD9pFRjNnPNg/CzJPuQAzUujMIM1vVeM=
|
cloud.google.com/go/kms v1.15.5 h1:pj1sRfut2eRbD9pFRjNnPNg/CzJPuQAzUujMIM1vVeM=
|
||||||
cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI=
|
cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI=
|
||||||
cloud.google.com/go/storage v1.36.0 h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8=
|
cloud.google.com/go/storage v1.37.0 h1:WI8CsaFO8Q9KjPVtsZ5Cmi0dXV25zMoX0FklT7c3Jm4=
|
||||||
cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8=
|
cloud.google.com/go/storage v1.37.0/go.mod h1:i34TiT2IhiNDmcj65PqwCjcoUX7Z5pLzS8DEmoiFq1k=
|
||||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
|
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 h1:lGlwhPtrX6EVml1hO0ivjkUxsSyl4dsiw9qcA1k/3IQ=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 h1:lGlwhPtrX6EVml1hO0ivjkUxsSyl4dsiw9qcA1k/3IQ=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1/go.mod h1:RKUqNu35KJYcVG/fqTRqmuXJZYNhYkBrnC/hX7yGbTA=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1/go.mod h1:RKUqNu35KJYcVG/fqTRqmuXJZYNhYkBrnC/hX7yGbTA=
|
||||||
|
@ -43,8 +43,8 @@ github.com/aws/aws-sdk-go-v2/credentials v1.16.16 h1:8q6Rliyv0aUFAVtzaldUEcS+T5g
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.16/go.mod h1:UHVZrdUsv63hPXFo1H7c5fEneoVo9UXiz36QG1GEPi0=
|
github.com/aws/aws-sdk-go-v2/credentials v1.16.16/go.mod h1:UHVZrdUsv63hPXFo1H7c5fEneoVo9UXiz36QG1GEPi0=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.14 h1:ogP1WgyvN/qxPJkgtFMD7G2eKb5p/61Jomx+nIHXUQ4=
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.15 h1:2MUXyGW6dVaQz6aqycpbdLIH1NMcUI6kW6vQ0RabGYg=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.14/go.mod h1:nYd/WmIrXlBHW/5QwrZP81/Gz08wKi87nV6EI1kmqx4=
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.15/go.mod h1:aHbhbR6WEQgHAiRj41EQ2W47yOYwNtIkWTXmcAtYqj8=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw=
|
||||||
|
@ -63,8 +63,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10 h1:KOxnQeWy5sXyS
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10/go.mod h1:jMx5INQFYFYB3lQD9W0D8Ohgq6Wnl7NYOJ2TQndbulI=
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10/go.mod h1:jMx5INQFYFYB3lQD9W0D8Ohgq6Wnl7NYOJ2TQndbulI=
|
||||||
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.19.6 h1:JWy+uLKZQR/9a3gQ+jQa28FEJ/41Z0spdbbQodaXFeA=
|
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.19.6 h1:JWy+uLKZQR/9a3gQ+jQa28FEJ/41Z0spdbbQodaXFeA=
|
||||||
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.19.6/go.mod h1:T2NcfuIuXWcuwVwg3rBIW6h1cfzCdrzSn4Hs0KltND8=
|
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.19.6/go.mod h1:T2NcfuIuXWcuwVwg3rBIW6h1cfzCdrzSn4Hs0KltND8=
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0 h1:PJTdBMsyvra6FtED7JZtDpQrIAflYDHFoZAu/sKYkwU=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.48.1 h1:5XNlsBsEvBZBMO6p82y+sqpWg8j5aBCe+5C2GBFgqBQ=
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.48.0/go.mod h1:4qXHrG1Ne3VGIMZPCB8OjH/pLFO94sKABIusjh0KWPU=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.48.1/go.mod h1:4qXHrG1Ne3VGIMZPCB8OjH/pLFO94sKABIusjh0KWPU=
|
||||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.2 h1:A5sGOT/mukuU+4At1vkSIWAN8tPwPCoYZBp7aruR540=
|
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.2 h1:A5sGOT/mukuU+4At1vkSIWAN8tPwPCoYZBp7aruR540=
|
||||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.2/go.mod h1:qutL00aW8GSo2D0I6UEOqMvRS3ZyuBrOC1BLe5D2jPc=
|
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.2/go.mod h1:qutL00aW8GSo2D0I6UEOqMvRS3ZyuBrOC1BLe5D2jPc=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 h1:eajuO3nykDPdYicLlP3AGgOyVN3MOlFmZv7WGTuJPow=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 h1:eajuO3nykDPdYicLlP3AGgOyVN3MOlFmZv7WGTuJPow=
|
||||||
|
|
|
@ -228,19 +228,19 @@ func (b *Binding) HasProxy() bool {
|
||||||
// GetTLSDescription returns the TLS mode as string
|
// GetTLSDescription returns the TLS mode as string
|
||||||
func (b *Binding) GetTLSDescription() string {
|
func (b *Binding) GetTLSDescription() string {
|
||||||
if certMgr == nil {
|
if certMgr == nil {
|
||||||
return "Disabled"
|
return util.I18nFTPTLSDisabled
|
||||||
}
|
}
|
||||||
switch b.TLSMode {
|
switch b.TLSMode {
|
||||||
case 1:
|
case 1:
|
||||||
return "Explicit required"
|
return util.I18nFTPTLSExplicit
|
||||||
case 2:
|
case 2:
|
||||||
return "Implicit"
|
return util.I18nFTPTLSImplicit
|
||||||
}
|
}
|
||||||
|
|
||||||
if certMgr.HasCertificate(common.DefaultTLSKeyPaidID) || certMgr.HasCertificate(b.GetAddress()) {
|
if certMgr.HasCertificate(common.DefaultTLSKeyPaidID) || certMgr.HasCertificate(b.GetAddress()) {
|
||||||
return "Plain and explicit"
|
return util.I18nFTPTLSMixed
|
||||||
}
|
}
|
||||||
return "Disabled"
|
return util.I18nFTPTLSDisabled
|
||||||
}
|
}
|
||||||
|
|
||||||
// PortRange defines a port range
|
// PortRange defines a port range
|
||||||
|
|
|
@ -98,7 +98,6 @@ const (
|
||||||
templateMaintenance = "maintenance.html"
|
templateMaintenance = "maintenance.html"
|
||||||
templateMFA = "mfa.html"
|
templateMFA = "mfa.html"
|
||||||
templateSetup = "adminsetup.html"
|
templateSetup = "adminsetup.html"
|
||||||
pageStatusTitle = "Status"
|
|
||||||
pageEventRulesTitle = "Event rules"
|
pageEventRulesTitle = "Event rules"
|
||||||
pageEventActionsTitle = "Event actions"
|
pageEventActionsTitle = "Event actions"
|
||||||
pageMaintenanceTitle = "Maintenance"
|
pageMaintenanceTitle = "Maintenance"
|
||||||
|
@ -442,7 +441,7 @@ func loadAdminTemplates(templatesPath string) {
|
||||||
filepath.Join(templatesPath, templateAdminDir, templateEventAction),
|
filepath.Join(templatesPath, templateAdminDir, templateEventAction),
|
||||||
}
|
}
|
||||||
statusPaths := []string{
|
statusPaths := []string{
|
||||||
filepath.Join(templatesPath, templateCommonDir, templateCommonCSS),
|
filepath.Join(templatesPath, templateCommonDir, templateCommonBase),
|
||||||
filepath.Join(templatesPath, templateAdminDir, templateBase),
|
filepath.Join(templatesPath, templateAdminDir, templateBase),
|
||||||
filepath.Join(templatesPath, templateAdminDir, templateStatus),
|
filepath.Join(templatesPath, templateAdminDir, templateStatus),
|
||||||
}
|
}
|
||||||
|
@ -3311,7 +3310,7 @@ func (s *httpdServer) handleWebUpdateUserPost(w http.ResponseWriter, r *http.Req
|
||||||
func (s *httpdServer) handleWebGetStatus(w http.ResponseWriter, r *http.Request) {
|
func (s *httpdServer) handleWebGetStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||||
data := statusPage{
|
data := statusPage{
|
||||||
basePage: s.getBasePageData(pageStatusTitle, webStatusPath, r),
|
basePage: s.getBasePageData(util.I18nStatusTitle, webStatusPath, r),
|
||||||
Status: getServicesStatus(),
|
Status: getServicesStatus(),
|
||||||
}
|
}
|
||||||
renderAdminTemplate(w, templateStatus, data)
|
renderAdminTemplate(w, templateStatus, data)
|
||||||
|
|
|
@ -67,6 +67,7 @@ const (
|
||||||
I18nAddIPListTitle = "title.add_ip_list"
|
I18nAddIPListTitle = "title.add_ip_list"
|
||||||
I18nUpdateIPListTitle = "title.update_ip_list"
|
I18nUpdateIPListTitle = "title.update_ip_list"
|
||||||
I18nDefenderTitle = "title.defender"
|
I18nDefenderTitle = "title.defender"
|
||||||
|
I18nStatusTitle = "status.desc"
|
||||||
I18nErrorSetupInstallCode = "setup.install_code_mismatch"
|
I18nErrorSetupInstallCode = "setup.install_code_mismatch"
|
||||||
I18nInvalidAuth = "general.invalid_auth_request"
|
I18nInvalidAuth = "general.invalid_auth_request"
|
||||||
I18nError429Message = "general.error429"
|
I18nError429Message = "general.error429"
|
||||||
|
@ -225,6 +226,10 @@ const (
|
||||||
I18nErrorAdminSelfRole = "admin.self_role"
|
I18nErrorAdminSelfRole = "admin.self_role"
|
||||||
I18nErrorIpInvalid = "ip_list.ip_invalid"
|
I18nErrorIpInvalid = "ip_list.ip_invalid"
|
||||||
I18nErrorNetInvalid = "ip_list.net_invalid"
|
I18nErrorNetInvalid = "ip_list.net_invalid"
|
||||||
|
I18nFTPTLSDisabled = "status.tls_disabled"
|
||||||
|
I18nFTPTLSExplicit = "status.tls_explicit"
|
||||||
|
I18nFTPTLSImplicit = "status.tls_implicit"
|
||||||
|
I18nFTPTLSMixed = "status.tls_mixed"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewI18nError returns a I18nError wrappring the provided error
|
// NewI18nError returns a I18nError wrappring the provided error
|
||||||
|
|
|
@ -189,7 +189,7 @@ type PipeWriter interface {
|
||||||
GetWrittenBytes() int64
|
GetWrittenBytes() int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// PipeReader defines an interface representing a SFTPGo pipe writer
|
// PipeReader defines an interface representing a SFTPGo pipe reader
|
||||||
type PipeReader interface {
|
type PipeReader interface {
|
||||||
io.Reader
|
io.Reader
|
||||||
io.ReaderAt
|
io.ReaderAt
|
||||||
|
|
|
@ -234,7 +234,10 @@
|
||||||
"last_login": "Last login",
|
"last_login": "Last login",
|
||||||
"previous": "Previous",
|
"previous": "Previous",
|
||||||
"next": "Next",
|
"next": "Next",
|
||||||
"type": "Type"
|
"type": "Type",
|
||||||
|
"issuer": "Issuer",
|
||||||
|
"data_provider": "Database",
|
||||||
|
"driver": "Driver"
|
||||||
},
|
},
|
||||||
"fs": {
|
"fs": {
|
||||||
"view_file": "View file \"{{- path}}\"",
|
"view_file": "View file \"{{- path}}\"",
|
||||||
|
@ -741,5 +744,33 @@
|
||||||
"ip": "IP address",
|
"ip": "IP address",
|
||||||
"ban_time": "Blocked until",
|
"ban_time": "Blocked until",
|
||||||
"score": "Score"
|
"score": "Score"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"desc": "Status of services",
|
||||||
|
"ssh": "SSH/SFTP server",
|
||||||
|
"active": "Status: active",
|
||||||
|
"disabled": "Status: disabled",
|
||||||
|
"proxy_on": "PROXY protocol enabled",
|
||||||
|
"address": "Address",
|
||||||
|
"ssh_auths": "Authentication methods",
|
||||||
|
"ssh_commands": "Accepted commands",
|
||||||
|
"host_key": "Host key",
|
||||||
|
"fingeprint": "Fingerprint",
|
||||||
|
"algorithms": "Algorithms",
|
||||||
|
"algorithm": "Algorithm",
|
||||||
|
"ssh_pub_key_algo": "Public key authentication algorithms",
|
||||||
|
"ssh_mac_algo": "Message authentication code (MAC) algorithms",
|
||||||
|
"ssh_kex_algo": "Key exchange (KEX) algorithms",
|
||||||
|
"ssh_cipher_algo": "Ciphers",
|
||||||
|
"ftp": "FTP server",
|
||||||
|
"ftp_passive_range": "Passive mode port range",
|
||||||
|
"ftp_passive_ip": "Passive IP",
|
||||||
|
"tls": "TLS",
|
||||||
|
"tls_disabled": "Disabled",
|
||||||
|
"tls_explicit": "Explicit mode required (FTPES)",
|
||||||
|
"tls_implicit": "Implicit mode (FTPS), deprecated, prefer FTPES",
|
||||||
|
"tls_mixed": "Plain and explicit (FTPES) mode",
|
||||||
|
"webdav": "WebDAV server",
|
||||||
|
"rate_limiters": "Rate limiters"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -234,7 +234,10 @@
|
||||||
"last_login": "Ultimo accesso",
|
"last_login": "Ultimo accesso",
|
||||||
"previous": "Precedente",
|
"previous": "Precedente",
|
||||||
"next": "Successivo",
|
"next": "Successivo",
|
||||||
"type": "Tipo"
|
"type": "Tipo",
|
||||||
|
"issuer": "Emittente",
|
||||||
|
"data_provider": "Database",
|
||||||
|
"driver": "Driver"
|
||||||
},
|
},
|
||||||
"fs": {
|
"fs": {
|
||||||
"view_file": "Visualizza file \"{{- path}}\"",
|
"view_file": "Visualizza file \"{{- path}}\"",
|
||||||
|
@ -741,5 +744,33 @@
|
||||||
"ip": "Indirizzo IP",
|
"ip": "Indirizzo IP",
|
||||||
"ban_time": "Bloccato fino a",
|
"ban_time": "Bloccato fino a",
|
||||||
"score": "Punteggio"
|
"score": "Punteggio"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"desc": "Stato dei servizi",
|
||||||
|
"ssh": "Server SSH/SFTP",
|
||||||
|
"active": "Stato: attivo",
|
||||||
|
"disabled": "Stato: disabilitato",
|
||||||
|
"proxy_on": "Protocollo PROXY abilitato",
|
||||||
|
"address": "Indirizzo",
|
||||||
|
"ssh_auths": "Metodi di autenticazione",
|
||||||
|
"ssh_commands": "Comandi accettati",
|
||||||
|
"host_key": "Chiave host",
|
||||||
|
"fingeprint": "Impronta",
|
||||||
|
"algorithms": "Algoritmi",
|
||||||
|
"algorithm": "Algoritmo",
|
||||||
|
"ssh_pub_key_algo": "Algoritmi per l'autenticazione con chiave pubblica",
|
||||||
|
"ssh_mac_algo": "Algoritmi MAC",
|
||||||
|
"ssh_kex_algo": "Algoritmi KEX",
|
||||||
|
"ssh_cipher_algo": "Cifrari",
|
||||||
|
"ftp": "Server FTP",
|
||||||
|
"ftp_passive_range": "Intervallo di porte in modalità passiva",
|
||||||
|
"ftp_passive_ip": "IP per FTP passivo",
|
||||||
|
"tls": "TLS",
|
||||||
|
"tls_disabled": "Disabilitato",
|
||||||
|
"tls_explicit": "Modalità esplicita richiesta (FTPES)",
|
||||||
|
"tls_implicit": "Modalità implicita (FTPS), sconsigliato, FTPES è preferibile",
|
||||||
|
"tls_mixed": "In chiaro e modalità esplicita (FTPES)",
|
||||||
|
"webdav": "Server WebDAV",
|
||||||
|
"rate_limiters": "Rate limiters"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,178 +1,217 @@
|
||||||
<!--
|
<!--
|
||||||
Copyright (C) 2019 Nicola Murino
|
Copyright (C) 2024 Nicola Murino
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This WebUI uses the KeenThemes Mega Bundle, a proprietary theme:
|
||||||
it under the terms of the GNU Affero General Public License as published
|
|
||||||
by the Free Software Foundation, version 3.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
https://keenthemes.com/products/templates-mega-bundle
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
KeenThemes HTML/CSS/JS components are allowed for use only within the
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
SFTPGo product and restricted to be used in a resealable HTML template
|
||||||
|
that can compete with KeenThemes products anyhow.
|
||||||
|
|
||||||
|
This WebUI is allowed for use only within the SFTPGo product and
|
||||||
|
therefore cannot be used in derivative works/products without an
|
||||||
|
explicit grant from the SFTPGo Team (support@sftpgo.com).
|
||||||
-->
|
-->
|
||||||
{{template "base" .}}
|
{{template "base" .}}
|
||||||
|
|
||||||
{{define "title"}}{{.Title}}{{end}}
|
{{- define "page_body"}}
|
||||||
|
<div class="card shadow-sm">
|
||||||
{{define "page_body"}}
|
<div class="card-header bg-light">
|
||||||
|
<h3 data-i18n="{{.Title}}" class="card-title section-title"></h3>
|
||||||
<div class="card shadow mb-4">
|
|
||||||
<div class="card-header py-3">
|
|
||||||
<h6 class="m-0 font-weight-bold text-primary">Services</h6>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="card mb-4 {{ if .Status.SSH.IsActive}}border-left-success{{else}}border-left-info{{end}}">
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<h3 data-i18n="status.ssh" class="card-title section-title-inner">SSH/SFTP server</h3>
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="card-title font-weight-bold">SFTP/SSH server</h6>
|
<p class="fs-3 fw-semibold mb-4" {{if .Status.SSH.IsActive}}data-i18n="status.active"{{else}}data-i18n="status.disabled"{{end}}></p>
|
||||||
<p class="card-text">
|
{{- if .Status.SSH.IsActive}}
|
||||||
Status: {{ if .Status.SSH.IsActive}}"Started"{{else}}"Stopped"{{end}}
|
<div class="d-flex flex-column">
|
||||||
{{if .Status.SSH.IsActive}}
|
{{- range .Status.SSH.Bindings}}
|
||||||
<br>
|
<p class="fs-5 fw-semibold">
|
||||||
{{range .Status.SSH.Bindings}}
|
<span class="text-success" data-i18n="status.address"></span> "{{.GetAddress}}"
|
||||||
<br>
|
</p>
|
||||||
Address: "{{.GetAddress}}" {{if .HasProxy}}Proxy: ON{{end}}
|
{{- if .HasProxy}}
|
||||||
<br>
|
<p class="fs-5 fw-semibold">
|
||||||
{{end}}
|
<span class="text-success" data-i18n="status.proxy_on"></span>
|
||||||
Accepted authentications: "{{.Status.SSH.GetSupportedAuthsAsString}}"
|
</p>
|
||||||
<br>
|
{{- end}}
|
||||||
Accepted commands: "{{.Status.SSH.GetSSHCommandsAsString}}"
|
{{- end}}
|
||||||
<br>
|
</div>
|
||||||
{{range .Status.SSH.HostKeys}}
|
{{- range .Status.SSH.HostKeys}}
|
||||||
<br>
|
<div class="d-flex flex-column mt-10">
|
||||||
Host Key: "{{.Path}}"
|
<p class="fs-5 fw-semibold">
|
||||||
<br>
|
<span class="text-success" data-i18n="status.host_key"></span> "{{.Path}}"
|
||||||
Fingerprint: "{{.Fingerprint}}"
|
</p>
|
||||||
<br>
|
<p class="fs-5 fw-semibold">
|
||||||
Algorithms: "{{.GetAlgosAsString}}"
|
<span class="text-success" data-i18n="status.fingeprint"></span> "{{.Fingerprint}}"
|
||||||
<br>
|
</p>
|
||||||
{{end}}
|
<p class="fs-5 fw-semibold">
|
||||||
<br>
|
<span class="text-success" data-i18n="status.algorithms"></span> "{{.GetAlgosAsString}}"
|
||||||
Public key authentication algorithms: "{{.Status.SSH.GetPublicKeysAlgosAsString}}"
|
</p>
|
||||||
<br><br>
|
</div>
|
||||||
Message authentication algorithms: "{{.Status.SSH.GetMACsAsString}}"
|
{{- end}}
|
||||||
<br><br>
|
<div class="d-flex flex-column mt-10">
|
||||||
Key exchange algorithms: "{{.Status.SSH.GetKEXsAsString}}"
|
<p class="fs-5 fw-semibold">
|
||||||
<br><br>
|
<span class="text-success" data-i18n="status.ssh_commands"></span> "{{.Status.SSH.GetSSHCommandsAsString}}"
|
||||||
Ciphers: "{{.Status.SSH.GetCiphersAsString}}"
|
</p>
|
||||||
<br>
|
<p class="fs-5 fw-semibold">
|
||||||
{{end}}
|
<span class="text-success" data-i18n="status.ssh_auths"></span> "{{.Status.SSH.GetSupportedAuthsAsString}}"
|
||||||
</p>
|
</p>
|
||||||
|
<p class="fs-5 fw-semibold">
|
||||||
|
<span class="text-success" data-i18n="status.ssh_pub_key_algo"></span> "{{.Status.SSH.GetPublicKeysAlgosAsString}}"
|
||||||
|
</p>
|
||||||
|
<p class="fs-5 fw-semibold">
|
||||||
|
<span class="text-success" data-i18n="status.ssh_mac_algo"></span> "{{.Status.SSH.GetMACsAsString}}"
|
||||||
|
</p>
|
||||||
|
<p class="fs-5 fw-semibold">
|
||||||
|
<span class="text-success" data-i18n="status.ssh_kex_algo"></span> "{{.Status.SSH.GetKEXsAsString}}"
|
||||||
|
</p>
|
||||||
|
<p class="fs-5 fw-semibold">
|
||||||
|
<span class="text-success" data-i18n="status.ssh_cipher_algo"></span> "{{.Status.SSH.GetCiphersAsString}}"
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{{- end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-4 {{ if .Status.FTP.IsActive}}border-left-success{{else}}border-left-info{{end}}">
|
<div class="card mt-10">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<h3 data-i18n="status.ftp" class="card-title section-title-inner">FTP server</h3>
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="card-title font-weight-bold">FTP server</h6>
|
<p class="fs-3 fw-semibold mb-4" {{if .Status.FTP.IsActive}}data-i18n="status.active"{{else}}data-i18n="status.disabled"{{end}}></p>
|
||||||
<p class="card-text">
|
{{- if .Status.FTP.IsActive}}
|
||||||
Status: {{ if .Status.FTP.IsActive}}"Started"{{else}}"Stopped"{{end}}
|
<div class="d-flex flex-column">
|
||||||
{{if .Status.FTP.IsActive}}
|
{{- range .Status.FTP.Bindings}}
|
||||||
<br>
|
<p class="fs-5 fw-semibold">
|
||||||
{{range .Status.FTP.Bindings}}
|
<span class="text-success" data-i18n="status.address"></span> "{{.GetAddress}}"
|
||||||
<br>
|
</p>
|
||||||
Address: "{{.GetAddress}}" {{if .HasProxy}}Proxy: ON{{end}}
|
{{- if .HasProxy}}
|
||||||
<br>
|
<p class="fs-5 fw-semibold">
|
||||||
TLS: "{{.GetTLSDescription}}"
|
<span class="text-success" data-i18n="status.proxy_on"></span>
|
||||||
{{if .ForcePassiveIP}}
|
</p>
|
||||||
<br>
|
{{- end}}
|
||||||
Passive IP: {{.ForcePassiveIP}}
|
<p class="fs-5 fw-semibold">
|
||||||
{{end}}
|
<span class="text-success" data-i18n="status.tls"></span> <span data-i18n="{{.GetTLSDescription}}"></span>
|
||||||
<br>
|
</p>
|
||||||
{{range .PassiveIPOverrides}}
|
{{- if .ForcePassiveIP}}
|
||||||
Passive IP: {{.IP}} for networks: {{.GetNetworksAsString}}
|
<p class="fs-5 fw-semibold">
|
||||||
<br>
|
<span class="text-success" data-i18n="status.ftp_passive_ip"></span> "{{.ForcePassiveIP}}"
|
||||||
{{end}}
|
</p>
|
||||||
{{end}}
|
{{- end}}
|
||||||
<br>
|
{{- range .PassiveIPOverrides}}
|
||||||
Passive port range: "{{.Status.FTP.PassivePortRange.Start}}-{{.Status.FTP.PassivePortRange.End}}"
|
<p class="fs-5 fw-semibold">
|
||||||
{{end}}
|
<span class="text-success" data-i18n="status.ftp_passive_ip"></span> "{{.IP}} ({{.GetNetworksAsString}})"
|
||||||
</p>
|
</p>
|
||||||
|
{{- end}}
|
||||||
|
{{- end}}
|
||||||
|
</div>
|
||||||
|
<div class="d-flex flex-column mt-10">
|
||||||
|
<p class="fs-5 fw-semibold">
|
||||||
|
<span class="text-success" data-i18n="status.ftp_passive_range"></span> "{{.Status.FTP.PassivePortRange.Start}}-{{.Status.FTP.PassivePortRange.End}}"
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{{- end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-4 {{ if .Status.WebDAV.IsActive}}border-left-success{{else}}border-left-info{{end}}">
|
<div class="card mt-10">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<h3 data-i18n="status.webdav" class="card-title section-title-inner">WebDAV server</h3>
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="card-title font-weight-bold">WebDAV server</h6>
|
<p class="fs-3 fw-semibold mb-4" {{if .Status.WebDAV.IsActive}}data-i18n="status.active"{{else}}data-i18n="status.disabled"{{end}}></p>
|
||||||
<p class="card-text">
|
{{- if .Status.WebDAV.IsActive}}
|
||||||
Status: {{ if .Status.WebDAV.IsActive}}"Started"{{else}}"Stopped"{{end}}
|
<div class="d-flex flex-column">
|
||||||
{{if .Status.WebDAV.IsActive}}
|
{{- range .Status.WebDAV.Bindings}}
|
||||||
<br>
|
<p class="fs-5 fw-semibold">
|
||||||
{{range .Status.WebDAV.Bindings}}
|
<span class="text-success" data-i18n="status.address"></span> "{{.GetAddress}}"
|
||||||
<br>
|
</p>
|
||||||
Address: "{{.GetAddress}}"
|
<p class="fs-5 fw-semibold">
|
||||||
<br>
|
<span class="text-success" data-i18n="general.protocol"></span> {{if .EnableHTTPS}} HTTPS {{else}} HTTP {{end}}
|
||||||
Protocol: {{if .EnableHTTPS}} HTTPS {{else}} HTTP {{end}}
|
</p>
|
||||||
<br>
|
{{- end}}
|
||||||
{{end}}
|
</div>
|
||||||
{{end}}
|
{{- end}}
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-4 {{ if .Status.AllowList.IsActive}}border-left-success{{else}}border-left-info{{end}}">
|
<div class="card mt-10">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<h3 data-i18n="iplist.allow_list" class="card-title section-title-inner">Allow list</h3>
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="card-title font-weight-bold">Allow list</h6>
|
<p class="fs-3 fw-semibold mb-4" {{if .Status.AllowList.IsActive}}data-i18n="status.active"{{else}}data-i18n="status.disabled"{{end}}></p>
|
||||||
<p class="card-text">
|
|
||||||
Status: {{ if .Status.AllowList.IsActive}}"Enabled"{{else}}"Disabled"{{end}}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-4 {{ if .Status.Defender.IsActive}}border-left-success{{else}}border-left-info{{end}}">
|
<div class="card mt-10">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<h3 data-i18n="iplist.defender_list" class="card-title section-title-inner">Defender</h3>
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="card-title font-weight-bold">Defender</h6>
|
<p class="fs-3 fw-semibold mb-4" {{if .Status.Defender.IsActive}}data-i18n="status.active"{{else}}data-i18n="status.disabled"{{end}}></p>
|
||||||
<p class="card-text">
|
|
||||||
Status: {{ if .Status.Defender.IsActive}}"Enabled"{{else}}"Disabled"{{end}}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-4 {{ if .Status.RateLimiters.IsActive}}border-left-success{{else}}border-left-info{{end}}">
|
<div class="card mt-10">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<h3 data-i18n="status.rate_limiters" class="card-title section-title-inner">Rate limiters</h3>
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="card-title font-weight-bold">Rate limiters</h6>
|
<p class="fs-3 fw-semibold mb-4" {{if .Status.RateLimiters.IsActive}}data-i18n="status.active"{{else}}data-i18n="status.disabled"{{end}}></p>
|
||||||
<p class="card-text">
|
{{- if .Status.RateLimiters.IsActive}}
|
||||||
Status: {{ if .Status.RateLimiters.IsActive}}"Enabled"{{else}}"Disabled"{{end}}
|
<div class="d-flex flex-column">
|
||||||
{{if .Status.RateLimiters.IsActive}}
|
<p class="fs-5 fw-semibold">
|
||||||
<br>
|
<span class="text-success" data-i18n="iplist.protocols"></span> "{{.Status.RateLimiters.GetProtocolsAsString}}"
|
||||||
Protocols: {{.Status.RateLimiters.GetProtocolsAsString}}
|
</p>
|
||||||
{{end}}
|
</div>
|
||||||
</p>
|
{{- end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-4 {{ if .Status.MFA.IsActive}}border-left-success{{else}}border-left-info{{end}}">
|
<div class="card mt-10">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<h3 data-i18n="title.two_factor_auth" class="card-title section-title-inner">Two-factor authentication</h3>
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="card-title font-weight-bold">Multi-factor authentication</h6>
|
<p class="fs-3 fw-semibold mb-4" {{if .Status.MFA.IsActive}}data-i18n="status.active"{{else}}data-i18n="status.disabled"{{end}}></p>
|
||||||
<p class="card-text">
|
{{- if .Status.MFA.IsActive}}
|
||||||
Status: {{ if .Status.MFA.IsActive}}"Enabled"{{else}}"Disabled"{{end}}
|
{{range .Status.MFA.TOTPConfigs}}
|
||||||
{{ if .Status.MFA.IsActive}}
|
<div class="d-flex flex-column">
|
||||||
<br>
|
<p class="fs-5 fw-semibold">
|
||||||
Time-based one time passwords (RFC 6238) configurations:
|
<span class="text-success" data-i18n="general.configuration"></span> "{{.Name}}"
|
||||||
<br>
|
</p>
|
||||||
<ul>
|
<p class="fs-5 fw-semibold">
|
||||||
{{range .Status.MFA.TOTPConfigs}}
|
<span class="text-success" data-i18n="general.issuer"></span> "{{.Issuer}}"
|
||||||
<li>Name: "{{.Name}}", issuer: "{{.Issuer}}", HMAC algorithm: "{{.Algo}}"</li>
|
</p>
|
||||||
{{end}}
|
<p class="fs-5 fw-semibold">
|
||||||
</ul>
|
<span class="text-success" data-i18n="status.algorithm"></span> "{{.Algo}}"
|
||||||
{{end}}
|
</p>
|
||||||
</p>
|
</div>
|
||||||
|
{{- end}}
|
||||||
|
{{- end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-2 {{ if .Status.DataProvider.IsActive}}border-left-success{{else}}border-left-warning{{end}}">
|
<div class="card mt-10">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<h3 data-i18n="general.data_provider" class="card-title section-title-inner">Database</h3>
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h6 class="card-title font-weight-bold">Data provider</h6>
|
<p class="fs-3 fw-semibold mb-4" {{if .Status.DataProvider.IsActive}}data-i18n="status.active"{{else}}{{.Status.DataProvider.Error}}{{end}}></p>
|
||||||
<p class="card-text">
|
<div class="d-flex flex-column">
|
||||||
Status: {{ if .Status.DataProvider.IsActive}}"OK"{{else}}"{{.Status.DataProvider.Error}}"{{end}}
|
<p class="fs-5 fw-semibold">
|
||||||
<br>
|
<span class="text-success" data-i18n="general.driver"></span> "{{.Status.DataProvider.Driver}}"
|
||||||
Driver: "{{.Status.DataProvider.Driver}}"
|
</p>
|
||||||
</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{- end}}
|
||||||
{{end}}
|
|
Loading…
Reference in a new issue