From be7bea2e4146da9e50ba1568018866561b418aea Mon Sep 17 00:00:00 2001 From: Connor Wright Date: Sun, 29 Nov 2020 21:55:11 +0000 Subject: [PATCH 1/5] add the ability to replace values before echoing --- blacklist.go | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/blacklist.go b/blacklist.go index f7745b9..e221407 100644 --- a/blacklist.go +++ b/blacklist.go @@ -13,11 +13,14 @@ import ( // Options is the struct that gets passed in by the user to create the blacklist struct with // If BlockedResponse is null, we will download and use the created template (see examples/template.html) +// If ReplaceStrings is not null, then {{key}} will be replaced by the corresponding value +// By default, there are a few replace strings which automatically get populated, such as the user's IP address type Options struct { Debug bool BlockedResponse []byte BlockedIPs []string BlockedUserAgents []string + ReplaceStrings map[string]string } // Blacklist is the struct that we will use for all internal purposes @@ -26,6 +29,7 @@ type Blacklist struct { blockedIPs []string blockedUserAgents []string blockedResponse []byte + replaceStrings map[string]string } // New creates a new instance of the Blacklist middleware @@ -34,12 +38,19 @@ func New(options Options) iris.Handler { blockedIPs: options.BlockedIPs, blockedUserAgents: options.BlockedUserAgents, blockedResponse: options.BlockedResponse, + replaceStrings: options.ReplaceStrings, } if options.Debug { b.log = log.New(os.Stdout, "[blacklist] ", log.LstdFlags) } + // if there are no replace strings defined in the options struct, make a map so we can pass some default values + if b.replaceStrings == nil || len(b.replaceStrings) == 0 { + defaultReplaceStrings := make(map[string]string, 2) + b.replaceStrings = defaultReplaceStrings + } + // if the user has not specified a blocked response, then download the template and use that if b.blockedResponse == nil { b.log.Println("no blocked response specified, downloading template file") @@ -58,6 +69,17 @@ func New(options Options) iris.Handler { } +func (b *Blacklist) returnWithValuesReplaced() []byte { + blockedResponse := string(b.blockedResponse) + + for k, v := range b.replaceStrings { + b.log.Println(fmt.Sprintf("replacing {{%s}} with %s", k, v)) + blockedResponse = strings.Replace(blockedResponse, fmt.Sprintf("{{%s}}", k), v, -1) + } + + return []byte(blockedResponse) +} + func (b *Blacklist) downloadTemplateFile(url string) ([]byte, error) { resp, err := http.Get(url) @@ -81,11 +103,15 @@ func (b *Blacklist) Serve(ctx iris.Context) { userAgent := ctx.Request().UserAgent() b.log.Print(fmt.Sprintf("checking whether the user agent %s is blocked or not", userAgent)) + b.replaceStrings["ip"] = ctx.Request().RemoteAddr + b.replaceStrings["service"] = "Joe Nuts" + for _, v := range b.blockedUserAgents { if v == userAgent { b.log.Print(fmt.Sprintf("the user's user agent has been blocked. showing blocked page")) + ctx.StatusCode(http.StatusForbidden) - ctx.HTML(string(b.blockedResponse)) + ctx.HTML(string(b.returnWithValuesReplaced())) ctx.StopExecution() return @@ -98,8 +124,9 @@ func (b *Blacklist) Serve(ctx iris.Context) { for _, v := range b.blockedIPs { if strings.Contains(userIP, v) { b.log.Print(fmt.Sprintf("the user's IP has been blocked. showing blocked page")) + ctx.StatusCode(http.StatusForbidden) - ctx.HTML(string(b.blockedResponse)) + ctx.HTML(string(b.returnWithValuesReplaced())) ctx.StopExecution() return From 7dc768a1e304cc6b790e085c042572b28f2c2335 Mon Sep 17 00:00:00 2001 From: Connor Wright Date: Sun, 29 Nov 2020 21:56:18 +0000 Subject: [PATCH 2/5] haha oops --- blacklist.go | 1 - 1 file changed, 1 deletion(-) diff --git a/blacklist.go b/blacklist.go index e221407..e0bcabf 100644 --- a/blacklist.go +++ b/blacklist.go @@ -104,7 +104,6 @@ func (b *Blacklist) Serve(ctx iris.Context) { b.log.Print(fmt.Sprintf("checking whether the user agent %s is blocked or not", userAgent)) b.replaceStrings["ip"] = ctx.Request().RemoteAddr - b.replaceStrings["service"] = "Joe Nuts" for _, v := range b.blockedUserAgents { if v == userAgent { From 7cc388d93dcb778235059b417ca99044cf76a55e Mon Sep 17 00:00:00 2001 From: Connor Wright Date: Sun, 29 Nov 2020 22:00:33 +0000 Subject: [PATCH 3/5] update example --- example/main.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/example/main.go b/example/main.go index 07cc155..2b56c8f 100644 --- a/example/main.go +++ b/example/main.go @@ -8,13 +8,19 @@ import ( func main() { app := iris.New() + replaceValues := make(map[string]string, 1) + replaceValues["message"] = "This is a test" + // we dont specify BlockedResponse since blacklist.New will automatically download the template file // and use that if we dont specify one // you can always specify one yourself, it's just a byte array + // by default, ReplaceStrings will have {{ip}} replaced with the user's IP address (if it exists in the specified template) + // so you don't need to add that blacklistMiddleware := blacklist.New(blacklist.Options{ Debug: true, BlockedIPs: []string{"127.0.0.1", "::1"}, BlockedUserAgents: []string{}, + ReplaceStrings: replaceValues, }) app.Use(blacklistMiddleware) From 97dfd5e9c600e958f6ed879abf3c591710f1a266 Mon Sep 17 00:00:00 2001 From: Connor Wright Date: Sun, 29 Nov 2020 22:14:25 +0000 Subject: [PATCH 4/5] remove debug stuff --- blacklist.go | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/blacklist.go b/blacklist.go index e0bcabf..39fba5e 100644 --- a/blacklist.go +++ b/blacklist.go @@ -3,9 +3,7 @@ package blacklist import ( "fmt" "io/ioutil" - "log" "net/http" - "os" "strings" "github.com/kataras/iris/v12" @@ -25,7 +23,6 @@ type Options struct { // Blacklist is the struct that we will use for all internal purposes type Blacklist struct { - log *log.Logger blockedIPs []string blockedUserAgents []string blockedResponse []byte @@ -41,10 +38,6 @@ func New(options Options) iris.Handler { replaceStrings: options.ReplaceStrings, } - if options.Debug { - b.log = log.New(os.Stdout, "[blacklist] ", log.LstdFlags) - } - // if there are no replace strings defined in the options struct, make a map so we can pass some default values if b.replaceStrings == nil || len(b.replaceStrings) == 0 { defaultReplaceStrings := make(map[string]string, 2) @@ -53,15 +46,12 @@ func New(options Options) iris.Handler { // if the user has not specified a blocked response, then download the template and use that if b.blockedResponse == nil { - b.log.Println("no blocked response specified, downloading template file") - fileBytes, err := b.downloadTemplateFile("https://asphaltbot.com/middleware/blacklist/template.html") if err != nil { panic("[blacklist] unable to download file: " + err.Error()) } - b.log.Println(fmt.Sprintf("successfully downloaded template file")) b.blockedResponse = fileBytes } @@ -73,7 +63,6 @@ func (b *Blacklist) returnWithValuesReplaced() []byte { blockedResponse := string(b.blockedResponse) for k, v := range b.replaceStrings { - b.log.Println(fmt.Sprintf("replacing {{%s}} with %s", k, v)) blockedResponse = strings.Replace(blockedResponse, fmt.Sprintf("{{%s}}", k), v, -1) } @@ -101,13 +90,12 @@ func (b *Blacklist) downloadTemplateFile(url string) ([]byte, error) { // Serve performs some checks whether the user is blocked or not func (b *Blacklist) Serve(ctx iris.Context) { userAgent := ctx.Request().UserAgent() - b.log.Print(fmt.Sprintf("checking whether the user agent %s is blocked or not", userAgent)) b.replaceStrings["ip"] = ctx.Request().RemoteAddr for _, v := range b.blockedUserAgents { if v == userAgent { - b.log.Print(fmt.Sprintf("the user's user agent has been blocked. showing blocked page")) + fmt.Println(fmt.Sprintf("the user's user agent has been blocked. showing blocked page")) ctx.StatusCode(http.StatusForbidden) ctx.HTML(string(b.returnWithValuesReplaced())) @@ -118,11 +106,10 @@ func (b *Blacklist) Serve(ctx iris.Context) { } userIP := ctx.Request().RemoteAddr - b.log.Print(fmt.Sprintf("checking whether the IP %s is blocked or not", userIP)) for _, v := range b.blockedIPs { if strings.Contains(userIP, v) { - b.log.Print(fmt.Sprintf("the user's IP has been blocked. showing blocked page")) + fmt.Println(fmt.Sprintf("the user's IP has been blocked. showing blocked page")) ctx.StatusCode(http.StatusForbidden) ctx.HTML(string(b.returnWithValuesReplaced())) From 5db785f52b3203d33d262429fbed5b905fa452b5 Mon Sep 17 00:00:00 2001 From: Connor Wright Date: Sun, 29 Nov 2020 22:14:45 +0000 Subject: [PATCH 5/5] update example --- blacklist.go | 1 - example/main.go | 1 - 2 files changed, 2 deletions(-) diff --git a/blacklist.go b/blacklist.go index 39fba5e..335fed4 100644 --- a/blacklist.go +++ b/blacklist.go @@ -14,7 +14,6 @@ import ( // If ReplaceStrings is not null, then {{key}} will be replaced by the corresponding value // By default, there are a few replace strings which automatically get populated, such as the user's IP address type Options struct { - Debug bool BlockedResponse []byte BlockedIPs []string BlockedUserAgents []string diff --git a/example/main.go b/example/main.go index 2b56c8f..7b6c2b8 100644 --- a/example/main.go +++ b/example/main.go @@ -17,7 +17,6 @@ func main() { // by default, ReplaceStrings will have {{ip}} replaced with the user's IP address (if it exists in the specified template) // so you don't need to add that blacklistMiddleware := blacklist.New(blacklist.Options{ - Debug: true, BlockedIPs: []string{"127.0.0.1", "::1"}, BlockedUserAgents: []string{}, ReplaceStrings: replaceValues,