1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-08-18 07:36:24 -07:00

Finish ban checking and appeal submission (when allowed)

This commit is contained in:
Joshua Merrell 2018-10-07 12:20:10 -07:00
parent 7de18e93f3
commit 1167f8c472
6 changed files with 178 additions and 75 deletions

BIN
html/notbanned.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View file

@ -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</body>\n</html>")
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, "<br />")
}
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</body>\n</html>")
return
}
fmt.Fprintf(writer, banpageBuffer.String())
}

View file

@ -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)

View file

@ -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 := "<table style=\"border-collapse: collapse;\"><tr><th>Field name</th><th>Value</th><th>Type</th><th>Description</th></tr>\n"
@ -225,8 +235,8 @@ var funcMap = template.FuncMap{
tableOut += "</table>\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
},
}

View file

@ -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

View file

@ -18,14 +18,13 @@
<div id="top-pane">
<span id="site-title">{{.config.SiteName}}</span><br />
<span id="site-slogan">{{.config.SiteSlogan}}</span>
</div>
<br /><br />
</div><br />
<div class="section-block" style="margin: 0px 26px 0px 24px">
<div class="section-title-block">
<span class="section-title"><b>{{if bannedForever .ban}}YOUR'E BANNED, IDIOT!{{else}}YOU ARE BANNED :({{end}}</b></span>
<span class="section-title"><b>{{if bannedForever .ban}}YOUR'E PERMABANNED, IDIOT!{{else if isBanned .ban .banBoards}}YOU ARE BANNED :({{else}}YOU ARE NOT BANNED :){{end}}</b></span>
</div>
<div class="section-body" style="padding-top:8px">
<div id="ban-info" style="float:left">{{if eq $.ban.Boards ""}}
<div class="section-body" style="padding-top:8px">{{if not (isBanned .ban .banBoards)}}<div style="text-align:center;">You're not banned. Good job.</div><br /><img id="banpage-image" src="/notbanned.png" style="display: block;margin-left: auto;margin-right: auto;"/><br />{{else}}
<div id="ban-info" style="float:left">{{if eq .ban.Boards ""}}
You are banned from posting on <b>all boards</b> for the following reason:{{else}}
You are banned from posting on <b>{{.ban.Boards}}</b> for the following reason:{{end}}
<br /><br />
@ -35,12 +34,11 @@
{{if .ban.Permaban}}<b>not expire</b>{{else}}expire on <b>{{$expires_timestamp}}</b>{{end}}.<br />
Your IP address is <b>{{.ban.IP}}</b>.<br /><br />
{{if .ban.CanAppeal}}You may appeal this ban:<br />
<form id="appeal-form">
<textarea rows="4" cols="48" name="postmsg" id="postmsg" placeholder="Appeal message"></textarea><br />
<form id="appeal-form" action="/banned" method="POST">
<textarea rows="4" cols="48" name="appealmsg" id="postmsg" placeholder="Appeal message"></textarea><br />
<input type="submit" value="Submit" /><br />
</form>{{else}}You may <b>not</b> appeal this ban.<br />{{end}}
</div>
{{if bannedForever .ban}}
</div>{{if bannedForever .ban}}
<img id="banpage-image" src="/permabanned.jpg" style="float:right; margin: 4px 8px 8px 4px"/><br />
<audio id="jack" preload="auto" autobuffer loop>
<source src="{{.config.SiteWebfolder}}hittheroad.ogg" />
@ -49,7 +47,8 @@
</audio>
<script type="text/javascript">
document.getElementById("jack").play();
</script>{{else}}<img id="banpage-image" src="/banned.jpg" style="float:right; margin: 4px 8px 8px 4px"/><br />{{end}}
</div>
</script>{{else if isBanned .ban .banBoards}}
<img id="banpage-image" src="/banned.jpg" style="float:right; margin: 4px 8px 8px 4px"/><br />{{end}}
{{end}}</div>
</div>
{{template "global_footer.html" .}}