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:
parent
7de18e93f3
commit
1167f8c472
6 changed files with 178 additions and 75 deletions
BIN
html/notbanned.png
Normal file
BIN
html/notbanned.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
124
src/posting.go
124
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</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())
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
100
src/template.go
100
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 := "<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
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" .}}
|
Loading…
Add table
Add a link
Reference in a new issue