WebUI: extract a common struct for all pages

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
Nicola Murino 2023-11-25 18:30:56 +01:00
parent ed828458ab
commit 74836af66e
No known key found for this signature in database
GPG key ID: 935D2952DEC4EECF
4 changed files with 130 additions and 140 deletions

View file

@ -162,14 +162,13 @@ func (s *httpdServer) refreshCookie(next http.Handler) http.Handler {
func (s *httpdServer) renderClientLoginPage(w http.ResponseWriter, r *http.Request, error, ip string) {
data := loginPage{
CurrentURL: webClientLoginPath,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
CSPNonce: secure.CSPNonce(r.Context()),
StaticURL: webStaticFilesPath,
Branding: s.binding.Branding.WebClient,
FormDisabled: s.binding.isWebClientLoginFormDisabled(),
commonBasePage: getCommonBasePage(r),
CurrentURL: webClientLoginPath,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
Branding: s.binding.Branding.WebClient,
FormDisabled: s.binding.isWebClientLoginFormDisabled(),
}
if next := r.URL.Query().Get("next"); strings.HasPrefix(next, webClientFilesPath) {
data.CurrentURL += "?next=" + url.QueryEscape(next)
@ -575,14 +574,13 @@ func (s *httpdServer) handleWebAdminLoginPost(w http.ResponseWriter, r *http.Req
func (s *httpdServer) renderAdminLoginPage(w http.ResponseWriter, r *http.Request, error, ip string) {
data := loginPage{
CurrentURL: webAdminLoginPath,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
CSPNonce: secure.CSPNonce(r.Context()),
StaticURL: webStaticFilesPath,
Branding: s.binding.Branding.WebAdmin,
FormDisabled: s.binding.isWebAdminLoginFormDisabled(),
commonBasePage: getCommonBasePage(r),
CurrentURL: webAdminLoginPath,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
Branding: s.binding.Branding.WebAdmin,
FormDisabled: s.binding.isWebAdminLoginFormDisabled(),
}
if s.binding.showClientLoginURL() {
data.AltLoginURL = webClientLoginPath

View file

@ -15,7 +15,10 @@
package httpd
import (
"net/http"
"strings"
"github.com/unrolled/secure"
)
const (
@ -41,13 +44,17 @@ const (
templateCommonBase = "base.html"
)
type commonBasePage struct {
CSPNonce string
StaticURL string
}
type loginPage struct {
commonBasePage
CurrentURL string
Version string
Error string
CSRFToken string
CSPNonce string
StaticURL string
AltLoginURL string
AltLoginName string
ForgotPwdURL string
@ -57,34 +64,31 @@ type loginPage struct {
}
type twoFactorPage struct {
commonBasePage
CurrentURL string
Version string
Error string
CSRFToken string
CSPNonce string
StaticURL string
RecoveryURL string
Title string
Branding UIBranding
}
type forgotPwdPage struct {
commonBasePage
CurrentURL string
Error string
CSRFToken string
CSPNonce string
StaticURL string
LoginURL string
Title string
Branding UIBranding
}
type resetPwdPage struct {
commonBasePage
CurrentURL string
Error string
CSRFToken string
CSPNonce string
StaticURL string
LoginURL string
Title string
Branding UIBranding
@ -104,3 +108,10 @@ func getSliceFromDelimitedValues(values, delimiter string) []string {
func hasPrefixAndSuffix(key, prefix, suffix string) bool {
return strings.HasPrefix(key, prefix) && strings.HasSuffix(key, suffix)
}
func getCommonBasePage(r *http.Request) commonBasePage {
return commonBasePage{
CSPNonce: secure.CSPNonce(r.Context()),
StaticURL: webStaticFilesPath,
}
}

View file

@ -32,7 +32,6 @@ import (
"github.com/go-chi/render"
"github.com/sftpgo/sdk"
sdkkms "github.com/sftpgo/sdk/kms"
"github.com/unrolled/secure"
"github.com/drakkan/sftpgo/v2/internal/acme"
"github.com/drakkan/sftpgo/v2/internal/common"
@ -132,6 +131,7 @@ var (
)
type basePage struct {
commonBasePage
Title string
CurrentURL string
UsersURL string
@ -164,7 +164,6 @@ type basePage struct {
FolderQuotaScanURL string
StatusURL string
MaintenanceURL string
StaticURL string
UsersTitle string
AdminsTitle string
ConnectionsTitle string
@ -181,7 +180,6 @@ type basePage struct {
ConfigsTitle string
Version string
CSRFToken string
CSPNonce string
IsEventManagerPage bool
IsIPManagerPage bool
IsServerManagerPage bool
@ -697,6 +695,7 @@ func (s *httpdServer) getBasePageData(title, currentURL string, r *http.Request)
csrfToken = createCSRFToken(util.GetIPFromRemoteAddress(r.RemoteAddr))
}
return basePage{
commonBasePage: getCommonBasePage(r),
Title: title,
CurrentURL: currentURL,
UsersURL: webUsersPath,
@ -729,7 +728,6 @@ func (s *httpdServer) getBasePageData(title, currentURL string, r *http.Request)
StatusURL: webStatusPath,
FolderQuotaScanURL: webScanVFolderPath,
MaintenanceURL: webMaintenancePath,
StaticURL: webStaticFilesPath,
UsersTitle: pageUsersTitle,
AdminsTitle: pageAdminsTitle,
ConnectionsTitle: pageConnectionsTitle,
@ -753,7 +751,6 @@ func (s *httpdServer) getBasePageData(title, currentURL string, r *http.Request)
HasSearcher: plugin.Handler.HasSearcher(),
HasExternalLogin: isLoggedInWithOIDC(r),
CSRFToken: csrfToken,
CSPNonce: secure.CSPNonce(r.Context()),
Branding: s.binding.Branding.WebAdmin,
}
}
@ -802,55 +799,51 @@ func (s *httpdServer) renderNotFoundPage(w http.ResponseWriter, r *http.Request,
func (s *httpdServer) renderForgotPwdPage(w http.ResponseWriter, r *http.Request, error, ip string) {
data := forgotPwdPage{
CurrentURL: webAdminForgotPwdPath,
Error: error,
CSRFToken: createCSRFToken(ip),
CSPNonce: secure.CSPNonce(r.Context()),
StaticURL: webStaticFilesPath,
Title: pageForgotPwdTitle,
Branding: s.binding.Branding.WebAdmin,
commonBasePage: getCommonBasePage(r),
CurrentURL: webAdminForgotPwdPath,
Error: error,
CSRFToken: createCSRFToken(ip),
Title: pageForgotPwdTitle,
Branding: s.binding.Branding.WebAdmin,
}
renderAdminTemplate(w, templateForgotPassword, data)
}
func (s *httpdServer) renderResetPwdPage(w http.ResponseWriter, r *http.Request, error, ip string) {
data := resetPwdPage{
CurrentURL: webAdminResetPwdPath,
Error: error,
CSRFToken: createCSRFToken(ip),
CSPNonce: secure.CSPNonce(r.Context()),
StaticURL: webStaticFilesPath,
Title: pageResetPwdTitle,
Branding: s.binding.Branding.WebAdmin,
commonBasePage: getCommonBasePage(r),
CurrentURL: webAdminResetPwdPath,
Error: error,
CSRFToken: createCSRFToken(ip),
Title: pageResetPwdTitle,
Branding: s.binding.Branding.WebAdmin,
}
renderAdminTemplate(w, templateResetPassword, data)
}
func (s *httpdServer) renderTwoFactorPage(w http.ResponseWriter, r *http.Request, error, ip string) {
data := twoFactorPage{
Title: pageTwoFactorTitle,
CurrentURL: webAdminTwoFactorPath,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
CSPNonce: secure.CSPNonce(r.Context()),
StaticURL: webStaticFilesPath,
RecoveryURL: webAdminTwoFactorRecoveryPath,
Branding: s.binding.Branding.WebAdmin,
commonBasePage: getCommonBasePage(r),
Title: pageTwoFactorTitle,
CurrentURL: webAdminTwoFactorPath,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
RecoveryURL: webAdminTwoFactorRecoveryPath,
Branding: s.binding.Branding.WebAdmin,
}
renderAdminTemplate(w, templateTwoFactor, data)
}
func (s *httpdServer) renderTwoFactorRecoveryPage(w http.ResponseWriter, r *http.Request, error, ip string) {
data := twoFactorPage{
Title: pageTwoFactorRecoveryTitle,
CurrentURL: webAdminTwoFactorRecoveryPath,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
CSPNonce: secure.CSPNonce(r.Context()),
StaticURL: webStaticFilesPath,
Branding: s.binding.Branding.WebAdmin,
commonBasePage: getCommonBasePage(r),
Title: pageTwoFactorRecoveryTitle,
CurrentURL: webAdminTwoFactorRecoveryPath,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
Branding: s.binding.Branding.WebAdmin,
}
renderAdminTemplate(w, templateTwoFactorRecovery, data)
}

View file

@ -34,7 +34,6 @@ import (
"github.com/go-chi/render"
"github.com/rs/xid"
"github.com/sftpgo/sdk"
"github.com/unrolled/secure"
"github.com/drakkan/sftpgo/v2/internal/common"
"github.com/drakkan/sftpgo/v2/internal/dataprovider"
@ -99,6 +98,7 @@ func isZeroTime(t time.Time) bool {
}
type baseClientPage struct {
commonBasePage
Title string
CurrentURL string
FilesURL string
@ -107,7 +107,6 @@ type baseClientPage struct {
ProfileURL string
PingURL string
ChangePwdURL string
StaticURL string
LogoutURL string
LoginURL string
EditURL string
@ -118,7 +117,6 @@ type baseClientPage struct {
ProfileTitle string
Version string
CSRFToken string
CSPNonce string
LoggedUser *dataprovider.User
Branding UIBranding
}
@ -129,11 +127,10 @@ type dirMapping struct {
}
type viewPDFPage struct {
Title string
URL string
StaticURL string
CSPNonce string
Branding UIBranding
commonBasePage
Title string
URL string
Branding UIBranding
}
type editFilePage struct {
@ -167,12 +164,11 @@ type filesPage struct {
}
type shareLoginPage struct {
commonBasePage
CurrentURL string
Version string
Error string
CSRFToken string
CSPNonce string
StaticURL string
Branding UIBranding
}
@ -553,27 +549,26 @@ func (s *httpdServer) getBaseClientPageData(title, currentURL string, r *http.Re
v := version.Get()
data := baseClientPage{
Title: title,
CurrentURL: currentURL,
FilesURL: webClientFilesPath,
SharesURL: webClientSharesPath,
ShareURL: webClientSharePath,
ProfileURL: webClientProfilePath,
PingURL: webClientPingPath,
ChangePwdURL: webChangeClientPwdPath,
StaticURL: webStaticFilesPath,
LogoutURL: webClientLogoutPath,
EditURL: webClientEditFilePath,
MFAURL: webClientMFAPath,
MFATitle: pageClient2FATitle,
FilesTitle: pageClientFilesTitle,
SharesTitle: pageClientSharesTitle,
ProfileTitle: pageClientProfileTitle,
Version: fmt.Sprintf("%v-%v", v.Version, v.CommitHash),
CSRFToken: csrfToken,
CSPNonce: secure.CSPNonce(r.Context()),
LoggedUser: getUserFromToken(r),
Branding: s.binding.Branding.WebClient,
commonBasePage: getCommonBasePage(r),
Title: title,
CurrentURL: currentURL,
FilesURL: webClientFilesPath,
SharesURL: webClientSharesPath,
ShareURL: webClientSharePath,
ProfileURL: webClientProfilePath,
PingURL: webClientPingPath,
ChangePwdURL: webChangeClientPwdPath,
LogoutURL: webClientLogoutPath,
EditURL: webClientEditFilePath,
MFAURL: webClientMFAPath,
MFATitle: pageClient2FATitle,
FilesTitle: pageClientFilesTitle,
SharesTitle: pageClientSharesTitle,
ProfileTitle: pageClientProfileTitle,
Version: fmt.Sprintf("%v-%v", v.Version, v.CommitHash),
CSRFToken: csrfToken,
LoggedUser: getUserFromToken(r),
Branding: s.binding.Branding.WebClient,
}
if !strings.HasPrefix(r.RequestURI, webClientPubSharesPath) {
data.LoginURL = webClientLoginPath
@ -583,41 +578,38 @@ func (s *httpdServer) getBaseClientPageData(title, currentURL string, r *http.Re
func (s *httpdServer) renderClientForgotPwdPage(w http.ResponseWriter, r *http.Request, error, ip string) {
data := forgotPwdPage{
CurrentURL: webClientForgotPwdPath,
Error: error,
CSRFToken: createCSRFToken(ip),
CSPNonce: secure.CSPNonce(r.Context()),
StaticURL: webStaticFilesPath,
LoginURL: webClientLoginPath,
Title: pageClientForgotPwdTitle,
Branding: s.binding.Branding.WebClient,
commonBasePage: getCommonBasePage(r),
CurrentURL: webClientForgotPwdPath,
Error: error,
CSRFToken: createCSRFToken(ip),
LoginURL: webClientLoginPath,
Title: pageClientForgotPwdTitle,
Branding: s.binding.Branding.WebClient,
}
renderClientTemplate(w, templateForgotPassword, data)
}
func (s *httpdServer) renderClientResetPwdPage(w http.ResponseWriter, r *http.Request, error, ip string) {
data := resetPwdPage{
CurrentURL: webClientResetPwdPath,
Error: error,
CSRFToken: createCSRFToken(ip),
CSPNonce: secure.CSPNonce(r.Context()),
StaticURL: webStaticFilesPath,
LoginURL: webClientLoginPath,
Title: pageClientResetPwdTitle,
Branding: s.binding.Branding.WebClient,
commonBasePage: getCommonBasePage(r),
CurrentURL: webClientResetPwdPath,
Error: error,
CSRFToken: createCSRFToken(ip),
LoginURL: webClientLoginPath,
Title: pageClientResetPwdTitle,
Branding: s.binding.Branding.WebClient,
}
renderClientTemplate(w, templateResetPassword, data)
}
func (s *httpdServer) renderShareLoginPage(w http.ResponseWriter, r *http.Request, error, ip string) {
data := shareLoginPage{
CurrentURL: r.RequestURI,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
CSPNonce: secure.CSPNonce(r.Context()),
StaticURL: webStaticFilesPath,
Branding: s.binding.Branding.WebClient,
commonBasePage: getCommonBasePage(r),
CurrentURL: r.RequestURI,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
Branding: s.binding.Branding.WebClient,
}
renderClientTemplate(w, templateShareLogin, data)
}
@ -665,15 +657,14 @@ func (s *httpdServer) renderClientNotFoundPage(w http.ResponseWriter, r *http.Re
func (s *httpdServer) renderClientTwoFactorPage(w http.ResponseWriter, r *http.Request, error, ip string) {
data := twoFactorPage{
Title: pageTwoFactorTitle,
CurrentURL: webClientTwoFactorPath,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
CSPNonce: secure.CSPNonce(r.Context()),
StaticURL: webStaticFilesPath,
RecoveryURL: webClientTwoFactorRecoveryPath,
Branding: s.binding.Branding.WebClient,
commonBasePage: getCommonBasePage(r),
Title: pageTwoFactorTitle,
CurrentURL: webClientTwoFactorPath,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
RecoveryURL: webClientTwoFactorRecoveryPath,
Branding: s.binding.Branding.WebClient,
}
if next := r.URL.Query().Get("next"); strings.HasPrefix(next, webClientFilesPath) {
data.CurrentURL += "?next=" + url.QueryEscape(next)
@ -683,14 +674,13 @@ func (s *httpdServer) renderClientTwoFactorPage(w http.ResponseWriter, r *http.R
func (s *httpdServer) renderClientTwoFactorRecoveryPage(w http.ResponseWriter, r *http.Request, error, ip string) {
data := twoFactorPage{
Title: pageTwoFactorRecoveryTitle,
CurrentURL: webClientTwoFactorRecoveryPath,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
CSPNonce: secure.CSPNonce(r.Context()),
StaticURL: webStaticFilesPath,
Branding: s.binding.Branding.WebClient,
commonBasePage: getCommonBasePage(r),
Title: pageTwoFactorRecoveryTitle,
CurrentURL: webClientTwoFactorRecoveryPath,
Version: version.Get().Version,
Error: error,
CSRFToken: createCSRFToken(ip),
Branding: s.binding.Branding.WebClient,
}
renderClientTemplate(w, templateTwoFactorRecovery, data)
}
@ -1088,12 +1078,11 @@ func (s *httpdServer) handleShareViewPDF(w http.ResponseWriter, r *http.Request)
}
name := util.CleanPath(r.URL.Query().Get("path"))
data := viewPDFPage{
Title: path.Base(name),
commonBasePage: getCommonBasePage(r),
Title: path.Base(name),
URL: fmt.Sprintf("%s?path=%s&_=%d", path.Join(webClientPubSharesPath, share.ShareID, "getpdf"),
url.QueryEscape(name), time.Now().UTC().Unix()),
StaticURL: webStaticFilesPath,
CSPNonce: secure.CSPNonce(r.Context()),
Branding: s.binding.Branding.WebClient,
Branding: s.binding.Branding.WebClient,
}
renderClientTemplate(w, templateClientViewPDF, data)
}
@ -1704,11 +1693,10 @@ func (s *httpdServer) handleClientViewPDF(w http.ResponseWriter, r *http.Request
}
name = util.CleanPath(name)
data := viewPDFPage{
Title: path.Base(name),
URL: fmt.Sprintf("%s?path=%s&_=%d", webClientGetPDFPath, url.QueryEscape(name), time.Now().UTC().Unix()),
StaticURL: webStaticFilesPath,
CSPNonce: secure.CSPNonce(r.Context()),
Branding: s.binding.Branding.WebClient,
commonBasePage: getCommonBasePage(r),
Title: path.Base(name),
URL: fmt.Sprintf("%s?path=%s&_=%d", webClientGetPDFPath, url.QueryEscape(name), time.Now().UTC().Unix()),
Branding: s.binding.Branding.WebClient,
}
renderClientTemplate(w, templateClientViewPDF, data)
}