From 1167f8c4729cbe82b54d8a804479d1390ef1ce95 Mon Sep 17 00:00:00 2001 From: Joshua Merrell Date: Sun, 7 Oct 2018 12:20:10 -0700 Subject: [PATCH] Finish ban checking and appeal submission (when allowed) --- html/notbanned.png | Bin 0 -> 5680 bytes src/posting.go | 124 +++++++++++++++++++++++++++++++++++++---- src/server.go | 1 + src/template.go | 100 ++++++++++++++++++--------------- src/types.go | 7 --- templates/banpage.html | 21 ++++--- 6 files changed, 178 insertions(+), 75 deletions(-) create mode 100644 html/notbanned.png diff --git a/html/notbanned.png b/html/notbanned.png new file mode 100644 index 0000000000000000000000000000000000000000..ab9471332e04563892d056744c0786c746e47d50 GIT binary patch literal 5680 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 EKT=uHUH||9 literal 0 HcmV?d00001 diff --git a/src/posting.go b/src/posting.go index d8d47a37..dc427190 100755 --- a/src/posting.go +++ b/src/posting.go @@ -564,19 +564,74 @@ func bumpThread(postID, boardID int) error { // Checks check poster's name/tripcode/file checksum (from PostTable post) for banned status // returns ban table if the user is banned or errNotBanned if they aren't -func getBannedStatus(post *PostTable) (BanlistTable, error) { +func getBannedStatus(request *http.Request) (BanlistTable, error) { var banEntry BanlistTable - err := queryRowSQL("SELECT `ip`,`name`,`boards`,`timestamp`,`expires`,`permaban`,`reason`,`type`,`appeal_at`,`can_appeal` FROM `"+config.DBprefix+"banlist` WHERE `ip` = ? OR `name` = ? OR `filename` = ? OR `file_checksum` = ? ORDER BY `id` DESC LIMIT 1", - []interface{}{&post.IP, &post.Name, &post.Filename, &post.FileChecksum}, - []interface{}{ - &banEntry.IP, &banEntry.Name, &banEntry.Boards, &banEntry.Timestamp, - &banEntry.Expires, &banEntry.Permaban, &banEntry.Reason, &banEntry.Type, - &banEntry.AppealAt, &banEntry.CanAppeal}, + + formName := request.FormValue("postname") + var tripcode string + if formName != "" { + parsedName := parseName(formName) + tripcode += parsedName["name"] + if tc, ok := parsedName["tripcode"]; ok { + tripcode += "!" + tc + } + } + ip := getRealIP(request) + + var filename string + var checksum string + file, fileHandler, err := request.FormFile("imagefile") + defer func() { + if file != nil { + file.Close() + } + }() + if err == nil { + html.EscapeString(fileHandler.Filename) + if data, err2 := ioutil.ReadAll(file); err2 == nil { + checksum = fmt.Sprintf("%x", md5.Sum(data)) + } + } + + in := []interface{}{ip} + query := "SELECT `id`,`ip`,`name`,`boards`,`timestamp`,`expires`,`permaban`,`reason`,`type`,`appeal_at`,`can_appeal` FROM `" + config.DBprefix + "banlist` WHERE `ip` = ? " + + if tripcode != "" { + in = append(in, tripcode) + query += "OR `name` = ? " + } + if filename != "" { + in = append(in, filename) + query += "OR `filename` = ? " + } + if checksum != "" { + in = append(in, checksum) + query += "OR `file_checksum` = ? " + } + query += " ORDER BY `id` DESC LIMIT 1" + + err = queryRowSQL(query, in, []interface{}{ + &banEntry.ID, &banEntry.IP, &banEntry.Name, &banEntry.Boards, &banEntry.Timestamp, + &banEntry.Expires, &banEntry.Permaban, &banEntry.Reason, &banEntry.Type, + &banEntry.AppealAt, &banEntry.CanAppeal}, ) - println(1, banEntry.Timestamp) return banEntry, err } +func isBanned(ban BanlistTable, board string) bool { + if ban.Boards == "" && (ban.Expires.After(time.Now()) || ban.Permaban) { + return true + } + boardsArr := strings.Split(ban.Boards, ",") + for _, b := range boardsArr { + if b == board && (ban.Expires.After(time.Now()) || ban.Permaban) { + return true + } + } + + return false +} + func sinceLastPost(post *PostTable) int { var lastPostTime time.Time if err := queryRowSQL("SELECT `timestamp` FROM `"+config.DBprefix+"posts` WHERE `ip` = '?' ORDER BY `timestamp` DESC LIMIT 1", @@ -1020,18 +1075,21 @@ func makePost(writer http.ResponseWriter, request *http.Request) { } } - banStatus, err := getBannedStatus(&post) + banStatus, err := getBannedStatus(request) if err != nil && err != sql.ErrNoRows { handleError(1, "Error in getBannedStatus: "+err.Error()) serveErrorPage(writer, err.Error()) return } - if banStatus.IsBanned() { + + boards, _ := getBoardArr(nil, "") + + if isBanned(banStatus, boards[post.BoardID-1].Dir) { var banpage_buffer bytes.Buffer var banpage_html string banpage_buffer.Write([]byte("")) if err = banpage_tmpl.Execute(&banpage_buffer, map[string]interface{}{ - "config": config, "ban": banStatus, + "config": config, "ban": banStatus, "banBoards": boards[post.BoardID-1].Dir, }); err != nil { fmt.Fprintf(writer, banpage_html+handleError(1, err.Error())+"\n\n") return @@ -1049,7 +1107,6 @@ func makePost(writer http.ResponseWriter, request *http.Request) { postid, _ := result.LastInsertId() post.ID = int(postid) - boards, _ := getBoardArr(nil, "") // rebuild the board page buildBoards(false, post.BoardID) buildFrontPage() @@ -1113,3 +1170,46 @@ func formatMessage(message string) string { } return strings.Join(postLines, "
") } + +func bannedForever(ban BanlistTable) bool { + return ban.Permaban && !ban.CanAppeal && ban.Type == 3 && ban.Boards == "" +} + +func banHandler(writer http.ResponseWriter, request *http.Request) { + appealMsg := request.FormValue("appealmsg") + banStatus, err := getBannedStatus(request) + + if appealMsg != "" { + if bannedForever(banStatus) { + fmt.Fprint(writer, "No.") + return + } + escapedMsg := html.EscapeString(appealMsg) + if _, err = execSQL("INSERT INTO `"+config.DBprefix+"appeals` (`ban`,`message`) VALUES(?,?)", + banStatus.ID, escapedMsg, + ); err != nil { + serveErrorPage(writer, err.Error()) + } + fmt.Fprint(writer, + "Appeal sent. It will (hopefully) be read by a staff member. check "+config.SiteWebfolder+"banned occasionally for a response", + ) + return + } + + if err != nil && err != sql.ErrNoRows { + handleError(1, "Error in getBannedStatus: "+err.Error()) + serveErrorPage(writer, err.Error()) + return + } + + var banpageBuffer bytes.Buffer + + banpageBuffer.Write([]byte("")) + if err = banpage_tmpl.Execute(&banpageBuffer, map[string]interface{}{ + "config": config, "ban": banStatus, "banBoards": banStatus.Boards, + }); err != nil { + fmt.Fprintf(writer, handleError(1, err.Error())+"\n\n") + return + } + fmt.Fprintf(writer, banpageBuffer.String()) +} diff --git a/src/server.go b/src/server.go index 152db1f0..4c2774f5 100755 --- a/src/server.go +++ b/src/server.go @@ -139,6 +139,7 @@ func initServer() { // Compile regex for checking referrers. referrerRegex = regexp.MustCompile(config.DomainRegex) + server.AddNamespace("banned", banHandler) server.AddNamespace("manage", callManageFunction) server.AddNamespace("post", makePost) server.AddNamespace("util", utilHandler) diff --git a/src/template.go b/src/template.go index 5f264dea..5fe59383 100755 --- a/src/template.go +++ b/src/template.go @@ -11,15 +11,35 @@ import ( ) var funcMap = template.FuncMap{ + // Arithmetic functions "add": func(a, b int) int { return a + b }, "subtract": func(a, b int) int { return a - b }, - "len": func(arr []interface{}) int { - return len(arr) + + // Comparison functions (some copied from text/template for compatibility) + "ge": func(a int, b int) bool { + return a >= b }, + "gt": func(a int, b int) bool { + return a > b + }, + "le": func(a int, b int) bool { + return a <= b + }, + "lt": func(a int, b int) bool { + return a < b + }, + "intEq": func(a, b int) bool { + return a == b + }, + "isNil": func(i interface{}) bool { + return i == nil + }, + + // Array functions "getSlice": func(arr []interface{}, start, end int) []interface{} { slice := arr[start:end] defer func() { @@ -29,25 +49,28 @@ var funcMap = template.FuncMap{ }() return slice }, - "gt": func(a int, b int) bool { - return a > b + "len": func(arr []interface{}) int { + return len(arr) }, - "ge": func(a int, b int) bool { - return a >= b + + // String functions + "arrToString": arrToString, + "intToString": strconv.Itoa, + "escapeString": func(a string) string { + return html.EscapeString(a) }, - "lt": func(a int, b int) bool { - return a < b - }, - "le": func(a int, b int) bool { - return a <= b - }, - "makeLoop": func(n int, offset int) []int { - loopArr := make([]int, n) - for i := range loopArr { - loopArr[i] = i + offset + "formatFilesize": func(size_int int) string { + size := float32(size_int) + if size < 1000 { + return fmt.Sprintf("%d B", size_int) + } else if size <= 100000 { + return fmt.Sprintf("%0.1f KB", size/1024) + } else if size <= 100000000 { + return fmt.Sprintf("%0.2f MB", size/1024/1024) } - return loopArr + return fmt.Sprintf("%0.2f GB", size/1024/1024/1024) }, + "formatTimestamp": humanReadableTime, "printf": func(v int, format string, a ...interface{}) string { printf(v, format, a...) return "" @@ -97,21 +120,9 @@ var funcMap = template.FuncMap{ } return msg }, - "escapeString": func(a string) string { - return html.EscapeString(a) - }, - "isNil": func(i interface{}) bool { - return i == nil - }, - "intEq": func(a, b int) bool { - return a == b - }, - "intToString": strconv.Itoa, - "arrToString": arrToString, - "isStyleDefault": func(style string) bool { - return style == config.DefaultStyle - }, - "formatTimestamp": humanReadableTime, + + // Imageboard functions + "bannedForever": bannedForever, "getThreadID": func(post_i interface{}) (thread int) { post := post_i.(PostTable) if post.ParentID == 0 { @@ -151,17 +162,6 @@ var funcMap = template.FuncMap{ } return uploadType }, - "formatFilesize": func(size_int int) string { - size := float32(size_int) - if size < 1000 { - return fmt.Sprintf("%d B", size_int) - } else if size <= 100000 { - return fmt.Sprintf("%0.1f KB", size/1024) - } else if size <= 100000000 { - return fmt.Sprintf("%0.2f MB", size/1024/1024) - } - return fmt.Sprintf("%0.2f GB", size/1024/1024/1024) - }, "imageToThumbnailPath": func(img string) string { filetype := strings.ToLower(img[strings.LastIndex(img, ".")+1:]) if filetype == "gif" || filetype == "webm" { @@ -173,6 +173,16 @@ var funcMap = template.FuncMap{ } return img[0:index] + "t." + filetype }, + "isBanned": isBanned, + + // Template convenience functions + "makeLoop": func(n int, offset int) []int { + loopArr := make([]int, n) + for i := range loopArr { + loopArr[i] = i + offset + } + return loopArr + }, "generateConfigTable": func() string { configType := reflect.TypeOf(config) tableOut := "\n" @@ -225,8 +235,8 @@ var funcMap = template.FuncMap{ tableOut += "
Field nameValueTypeDescription
\n" return tableOut }, - "bannedForever": func(ban BanlistTable) bool { - return ban.Permaban && !ban.CanAppeal && ban.Type == 3 && ban.Boards == "" + "isStyleDefault": func(style string) bool { + return style == config.DefaultStyle }, } diff --git a/src/types.go b/src/types.go index ec7703ce..88d34f9a 100644 --- a/src/types.go +++ b/src/types.go @@ -96,13 +96,6 @@ type BanlistTable struct { CanAppeal bool } -func (bt *BanlistTable) IsBanned() bool { - if getSpecificSQLDateTime(bt.Expires) == "0001-01-01 00:00:00" || bt.Expires.After(time.Now()) { - return true - } - return false -} - type BannedHashesTable struct { ID uint Checksum string diff --git a/templates/banpage.html b/templates/banpage.html index cabbadc3..d7e46425 100644 --- a/templates/banpage.html +++ b/templates/banpage.html @@ -18,14 +18,13 @@
{{.config.SiteName}}
{{.config.SiteSlogan}} -
-

+
- {{if bannedForever .ban}}YOUR'E BANNED, IDIOT!{{else}}YOU ARE BANNED :({{end}} + {{if bannedForever .ban}}YOUR'E PERMABANNED, IDIOT!{{else if isBanned .ban .banBoards}}YOU ARE BANNED :({{else}}YOU ARE NOT BANNED :){{end}}
-
-
{{if eq $.ban.Boards ""}} +
{{if not (isBanned .ban .banBoards)}}
You're not banned. Good job.


{{else}} +
{{if eq .ban.Boards ""}} You are banned from posting on all boards for the following reason:{{else}} You are banned from posting on {{.ban.Boards}} for the following reason:{{end}}

@@ -35,12 +34,11 @@ {{if .ban.Permaban}}not expire{{else}}expire on {{$expires_timestamp}}{{end}}.
Your IP address is {{.ban.IP}}.

{{if .ban.CanAppeal}}You may appeal this ban:
-
-
+ +

{{else}}You may not appeal this ban.
{{end}} -
- {{if bannedForever .ban}} +
{{if bannedForever .ban}}
{{else}}
{{end}} -
+ {{else if isBanned .ban .banBoards}} +
{{end}} + {{end}}
{{template "global_footer.html" .}} \ No newline at end of file