Add ban html template (#142)

*  Add ban html template

* 📝 Add doc for custom ban page

* 🍱 fix Mathieu work

* 🍱 fix lint

* 🍱 fix lint

* 🍱 fix lint

* 🍱 fix lint

---------

Co-authored-by: Max Lerebourg <maxlerebourg@gmail.com>
This commit is contained in:
mathieuHa
2024-04-03 17:58:18 +02:00
committed by GitHub
co-authored by Max Lerebourg
parent 6059f23dc3
commit 615e7ccf69
13 changed files with 865 additions and 50 deletions
+6 -28
View File
@@ -7,7 +7,6 @@ import (
"html/template"
"net/http"
"net/url"
"os"
"strings"
cache "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/cache"
@@ -22,7 +21,7 @@ type Client struct {
siteKey string
secretKey string
gracePeriodSeconds int64
htmlPage *template.Template
captchaTemplate *template.Template
cacheClient *cache.Client
httpClient *http.Client
log *logger.Log
@@ -55,26 +54,8 @@ var (
}
)
func compileTemplate(path string) (*template.Template, error) {
var err error
if path == "" {
return nil, fmt.Errorf("no captcha template provided")
}
//nolint:gosec
b, err := os.ReadFile(path)
if err != nil {
return nil, err
}
html := string(b)
compiledTemplate, err := template.New("captcha").Parse(html)
if err != nil {
return nil, fmt.Errorf("impossible to compile captcha template: %w", err)
}
return compiledTemplate, nil
}
// New Initialize captcha client.
func (c *Client) New(log *logger.Log, cacheClient *cache.Client, httpClient *http.Client, provider, siteKey, secretKey, htmlPagePath string, gracePeriodSeconds int64) error {
func (c *Client) New(log *logger.Log, cacheClient *cache.Client, httpClient *http.Client, provider, siteKey, secretKey, captchaTemplatePath string, gracePeriodSeconds int64) error {
c.Valid = provider != ""
if !c.Valid {
return nil
@@ -82,11 +63,8 @@ func (c *Client) New(log *logger.Log, cacheClient *cache.Client, httpClient *htt
c.siteKey = siteKey
c.secretKey = secretKey
c.provider = provider
html, err := compileTemplate(htmlPagePath)
if err != nil {
return err
}
c.htmlPage = html
html, _ := configuration.GetHTMLTemplate(captchaTemplatePath)
c.captchaTemplate = html
c.gracePeriodSeconds = gracePeriodSeconds
c.log = log
c.httpClient = httpClient
@@ -108,13 +86,13 @@ func (c *Client) ServeHTTP(rw http.ResponseWriter, r *http.Request, remoteIP str
http.Redirect(rw, r, r.URL.String(), http.StatusFound)
return
}
err = c.htmlPage.Execute(rw, map[string]string{
err = c.captchaTemplate.Execute(rw, map[string]string{
"SiteKey": c.siteKey,
"FrontendJS": captcha[c.provider].js,
"FrontendKey": captcha[c.provider].key,
})
if err != nil {
c.log.Info("captcha:ServeHTTP Can't serve HTML")
c.log.Info(fmt.Sprintf("captcha:ServeHTTP captchaTemplateServe %s", err.Error()))
}
}
+31 -1
View File
@@ -5,6 +5,7 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
"html/template"
"net/http"
"net/url"
"os"
@@ -66,6 +67,7 @@ type Config struct {
RedisCachePassword string `json:"redisCachePassword,omitempty"`
RedisCachePasswordFile string `json:"redisCachePasswordFile,omitempty"`
RedisCacheDatabase string `json:"redisCacheDatabase,omitempty"`
BanHTMLFilePath string `json:"banHtmlFilePath,omitempty"`
CaptchaHTMLFilePath string `json:"captchaHtmlFilePath,omitempty"`
CaptchaProvider string `json:"captchaProvider,omitempty"`
CaptchaSiteKey string `json:"captchaSiteKey,omitempty"`
@@ -103,8 +105,9 @@ func New() *Config {
CaptchaProvider: "",
CaptchaSiteKey: "",
CaptchaSecretKey: "",
CaptchaHTMLFilePath: "/captcha.html",
CaptchaGracePeriodSeconds: 1800,
CaptchaHTMLFilePath: "/captcha.html",
BanHTMLFilePath: "",
ForwardedHeadersCustomName: "X-Forwarded-For",
ForwardedHeadersTrustedIPs: []string{},
ClientTrustedIPs: []string{},
@@ -142,6 +145,25 @@ func GetVariable(config *Config, key string) (string, error) {
return strings.TrimSpace(value), nil
}
// GetHTMLTemplate get compiled HTML template.
func GetHTMLTemplate(path string) (*template.Template, error) {
var err error
if path == "" {
return nil, fmt.Errorf("no html template provided")
}
//nolint:gosec
b, err := os.ReadFile(path)
if err != nil {
return nil, err
}
html := string(b)
compiledTemplate, err := template.New("html").Parse(html)
if err != nil {
return nil, fmt.Errorf("impossible to compile html template: %w", err)
}
return compiledTemplate, nil
}
// ValidateParams validate all the param gave by user.
//
//nolint:gocyclo,gocognit
@@ -178,6 +200,14 @@ func ValidateParams(config *Config) error {
if _, err := GetVariable(config, "CaptchaSecretKey"); err != nil {
return err
}
if _, err := GetHTMLTemplate(config.CaptchaHTMLFilePath); err != nil {
return err
}
}
if config.BanHTMLFilePath != "" {
if _, err := GetHTMLTemplate(config.BanHTMLFilePath); err != nil {
return err
}
}
if err := validateURL("CrowdsecLapi", config.CrowdsecLapiScheme, config.CrowdsecLapiHost); err != nil {