You can now disable slugs.
Split ops.log into ops.log and requests.log Moved the logs into the logs directory. Moved more password validation logic in the registration route into WeakPassword(). Tweaked the WeakPassword algorithm to cover more cases and to reduce the number of false positives. Fixed the error grammer in WeakPassword now that the linter isn't bothering me about that anymore. Fixed BuildGuildURL(). Removed some commented logging logic. Bad requests are no longer logged to the console. All bad routes are logged now. We now track the instance uptime on the Control Panel Debug Page. Added the executables for Linux to the .gitignore file. Added GopherJS as a dependency. Began work on transpiling WeakPassword to JavaScript in use in the client-side logic.
This commit is contained in:
parent
74e09efb63
commit
b32e8d6c21
|
@ -10,10 +10,10 @@ attachs/*
|
|||
uploads/avatar_*
|
||||
uploads/socialgroup_*
|
||||
backups/*.sql
|
||||
logs/*.log
|
||||
node_modules/*
|
||||
bin/*
|
||||
out/*
|
||||
logs/*
|
||||
*.exe
|
||||
*.exe~
|
||||
*.prof
|
||||
|
@ -21,3 +21,5 @@ logs/*
|
|||
.DS_Store
|
||||
.vscode/launch.json
|
||||
config.go
|
||||
Gosora
|
||||
Install
|
||||
|
|
|
@ -10,7 +10,7 @@ If you dislike it, please give us some feedback on how to make it better! We're
|
|||
|
||||
|
||||
# Features
|
||||
Basic Forum Functionality. All of the little things you would expect of any forum software. E.g. Common Moderation features, modlogs, theme system, avatars, bbcode parser, markdown parser, report system, per-forum permissions, group permissions and so on.
|
||||
Standard Forum Functionality. All of the little things you would expect of any forum software. E.g. Common Moderation features, modlogs, theme system, avatars, bbcode parser, markdown parser, report system, per-forum permissions, group permissions and so on.
|
||||
|
||||
Custom Pages. Under development. The Control Panel portion is incomplete, but you can create them by hand today. They're basically html/templates templates in the /pages/ folder.
|
||||
|
||||
|
@ -122,6 +122,8 @@ go get -u github.com/fsnotify/fsnotify
|
|||
|
||||
go get -u gopkg.in/src-d/go-git.v4/...
|
||||
|
||||
go get -u github.com/gopherjs/gopherjs
|
||||
|
||||
|
||||
go generate
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"../common"
|
||||
"github.com/gopherjs/gopherjs/js"
|
||||
)
|
||||
|
||||
func main() {
|
||||
js.Global.Set("weakPassword", func(password string, username string, email string) string {
|
||||
err := common.WeakPassword(password, username, email)
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return ""
|
||||
})
|
||||
}
|
|
@ -144,7 +144,7 @@ func BlankForum(fid int, link string, name string, desc string, active bool, pre
|
|||
}
|
||||
|
||||
func BuildForumURL(slug string, fid int) string {
|
||||
if slug == "" {
|
||||
if slug == "" || !Config.BuildSlugs {
|
||||
return "/forum/" + strconv.Itoa(fid)
|
||||
}
|
||||
return "/forum/" + slug + "." + strconv.Itoa(fid)
|
||||
|
|
|
@ -7,6 +7,13 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// TODO: Implement this and use it
|
||||
// TODO: Allow resources in spots other than /static/ and possibly even external domains (e.g. CDNs)
|
||||
type HeaderResource struct {
|
||||
Path string
|
||||
Preload bool
|
||||
}
|
||||
|
||||
type HeaderVars struct {
|
||||
NoticeList []string
|
||||
Scripts []string
|
||||
|
|
111
common/parser.go
111
common/parser.go
|
@ -1,7 +1,6 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
//"fmt"
|
||||
"bytes"
|
||||
"html"
|
||||
"net/url"
|
||||
|
@ -295,26 +294,18 @@ func ParseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
|||
}
|
||||
|
||||
// Search for URLs, mentions and hashlinks in the messages...
|
||||
//log.Print("Parser Loop!")
|
||||
var msgbytes = []byte(msg)
|
||||
var outbytes []byte
|
||||
msgbytes = append(msgbytes, SpaceGap...)
|
||||
//log.Printf("string(msgbytes) %+v\n", `"`+string(msgbytes)+`"`)
|
||||
var lastItem = 0
|
||||
var i = 0
|
||||
for ; len(msgbytes) > (i + 1); i++ {
|
||||
//log.Print("Index: ",i)
|
||||
//log.Print("Index Item: ",msgbytes[i])
|
||||
//log.Print("string(msgbytes[i]): ",string(msgbytes[i]))
|
||||
//log.Print("End Index")
|
||||
if (i == 0 && (msgbytes[0] > 32)) || ((msgbytes[i] < 33) && (msgbytes[i+1] > 32)) {
|
||||
//log.Print("IN ",msgbytes[i])
|
||||
if (i != 0) || msgbytes[i] < 33 {
|
||||
i++
|
||||
}
|
||||
|
||||
if msgbytes[i] == '#' {
|
||||
//log.Print("IN #")
|
||||
if bytes.Equal(msgbytes[i+1:i+5], []byte("tid-")) {
|
||||
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
||||
i += 5
|
||||
|
@ -337,13 +328,6 @@ func ParseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
|||
outbytes = append(outbytes, tidBit...)
|
||||
outbytes = append(outbytes, UrlClose...)
|
||||
lastItem = i
|
||||
|
||||
//log.Print("string(msgbytes): ",string(msgbytes))
|
||||
//log.Print("msgbytes: ",msgbytes)
|
||||
//log.Print("msgbytes[lastItem - 1]: ",msgbytes[lastItem - 1])
|
||||
//log.Print("lastItem - 1: ",lastItem - 1)
|
||||
//log.Print("msgbytes[lastItem]: ",msgbytes[lastItem])
|
||||
//log.Print("lastItem: ",lastItem)
|
||||
} else if bytes.Equal(msgbytes[i+1:i+5], []byte("rid-")) {
|
||||
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
||||
i += 5
|
||||
|
@ -391,7 +375,6 @@ func ParseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
|||
// TODO: Forum Shortcode Link
|
||||
}
|
||||
} else if msgbytes[i] == '@' {
|
||||
//log.Print("IN @")
|
||||
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
||||
i++
|
||||
start := i
|
||||
|
@ -415,19 +398,20 @@ func ParseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
|||
outbytes = append(outbytes, uidBit...)
|
||||
outbytes = append(outbytes, UrlClose...)
|
||||
lastItem = i
|
||||
} else if msgbytes[i] == 'h' || msgbytes[i] == 'f' || msgbytes[i] == 'g' {
|
||||
//log.Print("IN hfg")
|
||||
} else if msgbytes[i] == 'h' || msgbytes[i] == 'f' || msgbytes[i] == 'g' || msgbytes[i] == '/' {
|
||||
if msgbytes[i+1] == 't' && msgbytes[i+2] == 't' && msgbytes[i+3] == 'p' {
|
||||
if msgbytes[i+4] == 's' && msgbytes[i+5] == ':' && msgbytes[i+6] == '/' && msgbytes[i+7] == '/' {
|
||||
if msgbytes[i+4] == 's' && msgbytes[i+5] == ':' && msgbytes[i+6] == '/' {
|
||||
// Do nothing
|
||||
} else if msgbytes[i+4] == ':' && msgbytes[i+5] == '/' && msgbytes[i+6] == '/' {
|
||||
} else if msgbytes[i+4] == ':' && msgbytes[i+5] == '/' {
|
||||
// Do nothing
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
} else if msgbytes[i+1] == 't' && msgbytes[i+2] == 'p' && msgbytes[i+3] == ':' && msgbytes[i+4] == '/' && msgbytes[i+5] == '/' {
|
||||
} else if msgbytes[i+1] == 't' && msgbytes[i+2] == 'p' && msgbytes[i+3] == ':' && msgbytes[i+4] == '/' {
|
||||
// Do nothing
|
||||
} else if msgbytes[i+1] == 'i' && msgbytes[i+2] == 't' && msgbytes[i+3] == ':' && msgbytes[i+4] == '/' && msgbytes[i+5] == '/' {
|
||||
} else if msgbytes[i+1] == 'i' && msgbytes[i+2] == 't' && msgbytes[i+3] == ':' && msgbytes[i+4] == '/' {
|
||||
// Do nothing
|
||||
} else if msgbytes[i+1] == '/' {
|
||||
// Do nothing
|
||||
} else {
|
||||
continue
|
||||
|
@ -438,10 +422,6 @@ func ParseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
|||
urlLen := PartialURLBytesLen(msgbytes[i:])
|
||||
if msgbytes[i+urlLen] > 32 { // space and invisibles
|
||||
//log.Print("INVALID URL")
|
||||
//log.Print("msgbytes[i+urlLen]: ", msgbytes[i+urlLen])
|
||||
//log.Print("string(msgbytes[i+urlLen]): ", string(msgbytes[i+urlLen]))
|
||||
//log.Print("msgbytes[i:i+urlLen]: ", msgbytes[i:i+urlLen])
|
||||
//log.Print("string(msgbytes[i:i+urlLen]): ", string(msgbytes[i:i+urlLen]))
|
||||
outbytes = append(outbytes, InvalidURL...)
|
||||
i += urlLen
|
||||
continue
|
||||
|
@ -454,66 +434,7 @@ func ParseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
|||
continue
|
||||
}
|
||||
|
||||
if media.Type == "attach" {
|
||||
outbytes = append(outbytes, imageOpen...)
|
||||
outbytes = append(outbytes, []byte(media.URL+"?sectionID="+strconv.Itoa(sectionID)+"§ionType="+sectionType)...)
|
||||
outbytes = append(outbytes, imageOpen2...)
|
||||
outbytes = append(outbytes, []byte(media.URL+"?sectionID="+strconv.Itoa(sectionID)+"§ionType="+sectionType)...)
|
||||
outbytes = append(outbytes, imageClose...)
|
||||
i += urlLen
|
||||
lastItem = i
|
||||
continue
|
||||
} else if media.Type == "image" {
|
||||
outbytes = append(outbytes, imageOpen...)
|
||||
outbytes = append(outbytes, []byte(media.URL)...)
|
||||
outbytes = append(outbytes, imageOpen2...)
|
||||
outbytes = append(outbytes, []byte(media.URL)...)
|
||||
outbytes = append(outbytes, imageClose...)
|
||||
i += urlLen
|
||||
lastItem = i
|
||||
continue
|
||||
} else if media.Type == "raw" {
|
||||
outbytes = append(outbytes, []byte(media.Body)...)
|
||||
i += urlLen
|
||||
lastItem = i
|
||||
continue
|
||||
} else if media.Type != "" {
|
||||
outbytes = append(outbytes, unknownMedia...)
|
||||
i += urlLen
|
||||
continue
|
||||
}
|
||||
|
||||
outbytes = append(outbytes, UrlOpen...)
|
||||
outbytes = append(outbytes, msgbytes[i:i+urlLen]...)
|
||||
outbytes = append(outbytes, UrlOpen2...)
|
||||
outbytes = append(outbytes, msgbytes[i:i+urlLen]...)
|
||||
outbytes = append(outbytes, UrlClose...)
|
||||
i += urlLen
|
||||
lastItem = i
|
||||
} else if msgbytes[i] == '/' && msgbytes[i+1] == '/' {
|
||||
outbytes = append(outbytes, msgbytes[lastItem:i]...)
|
||||
urlLen := PartialURLBytesLen(msgbytes[i:])
|
||||
if msgbytes[i+urlLen] > 32 { // space and invisibles
|
||||
//log.Print("INVALID URL")
|
||||
//log.Print("msgbytes[i+urlLen]: ", msgbytes[i+urlLen])
|
||||
//log.Print("string(msgbytes[i+urlLen]): ", string(msgbytes[i+urlLen]))
|
||||
//log.Print("msgbytes[i:i+urlLen]: ", msgbytes[i:i+urlLen])
|
||||
//log.Print("string(msgbytes[i:i+urlLen]): ", string(msgbytes[i:i+urlLen]))
|
||||
outbytes = append(outbytes, InvalidURL...)
|
||||
i += urlLen
|
||||
continue
|
||||
}
|
||||
|
||||
//log.Print("VALID URL")
|
||||
//log.Print("msgbytes[i:i+urlLen]: ", msgbytes[i:i+urlLen])
|
||||
//log.Print("string(msgbytes[i:i+urlLen]): ", string(msgbytes[i:i+urlLen]))
|
||||
media, ok := parseMediaBytes(msgbytes[i : i+urlLen])
|
||||
if !ok {
|
||||
outbytes = append(outbytes, InvalidURL...)
|
||||
i += urlLen
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO: Reduce the amount of code duplication
|
||||
if media.Type == "attach" {
|
||||
outbytes = append(outbytes, imageOpen...)
|
||||
outbytes = append(outbytes, []byte(media.URL+"?sectionID="+strconv.Itoa(sectionID)+"§ionType="+sectionType)...)
|
||||
|
@ -555,11 +476,6 @@ func ParseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
|||
}
|
||||
|
||||
if lastItem != i && len(outbytes) != 0 {
|
||||
//log.Print("lastItem: ", msgbytes[lastItem])
|
||||
//log.Print("lastItem index: ", lastItem)
|
||||
//log.Print("i: ", i)
|
||||
//log.Print("lastItem to end: ", msgbytes[lastItem:])
|
||||
//log.Print("-----")
|
||||
calclen := len(msgbytes) - 10
|
||||
if calclen <= lastItem {
|
||||
calclen = lastItem
|
||||
|
@ -567,8 +483,6 @@ func ParseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
|||
outbytes = append(outbytes, msgbytes[lastItem:calclen]...)
|
||||
msg = string(outbytes)
|
||||
}
|
||||
//log.Print(`"`+string(outbytes)+`"`)
|
||||
//log.Print("msg",`"`+msg+`"`)
|
||||
|
||||
msg = strings.Replace(msg, "\n", "<br>", -1)
|
||||
msg = RunSshook("parse_assign", msg)
|
||||
|
@ -705,14 +619,10 @@ func parseMediaBytes(data []byte) (media MediaEmbed, ok bool) {
|
|||
return media, false
|
||||
}
|
||||
|
||||
//log.Print("url ", url)
|
||||
hostname := url.Hostname()
|
||||
scheme := url.Scheme
|
||||
port := url.Port()
|
||||
//log.Print("hostname ", hostname)
|
||||
//log.Print("scheme ", scheme)
|
||||
query := url.Query()
|
||||
//log.Printf("query %+v\n", query)
|
||||
|
||||
var samesite = hostname == "localhost" || hostname == Site.URL
|
||||
if samesite {
|
||||
|
@ -728,14 +638,9 @@ func parseMediaBytes(data []byte) (media MediaEmbed, ok bool) {
|
|||
}
|
||||
|
||||
path := url.EscapedPath()
|
||||
//log.Print("path", path)
|
||||
pathFrags := strings.Split(path, "/")
|
||||
//log.Printf("pathFrags %+v\n", pathFrags)
|
||||
//log.Print("scheme ", scheme)
|
||||
//log.Print("hostname ", hostname)
|
||||
if len(pathFrags) >= 2 {
|
||||
if samesite && pathFrags[1] == "attachs" && (scheme == "http" || scheme == "https") {
|
||||
//log.Print("Attachment")
|
||||
media.Type = "attach"
|
||||
var sport string
|
||||
// ? - Assumes the sysadmin hasn't mixed up the two standard ports
|
||||
|
|
|
@ -67,6 +67,7 @@ type config struct {
|
|||
StaffCSS string // ? - Move this into the settings table? Might be better to implement this as Group CSS
|
||||
DefaultForum int // The forum posts go in by default, this used to be covered by the Uncategorised Forum, but we want to replace it with a more robust solution. Make this a setting?
|
||||
MinifyTemplates bool
|
||||
BuildSlugs bool // TODO: Make this a setting?
|
||||
ServerCount int
|
||||
|
||||
Noavatar string // ? - Move this into the settings table?
|
||||
|
|
|
@ -388,7 +388,7 @@ func BlankTopic() *Topic {
|
|||
}
|
||||
|
||||
func BuildTopicURL(slug string, tid int) string {
|
||||
if slug == "" {
|
||||
if slug == "" || !Config.BuildSlugs {
|
||||
return "/topic/" + strconv.Itoa(tid)
|
||||
}
|
||||
return "/topic/" + slug + "." + strconv.Itoa(tid)
|
||||
|
|
|
@ -426,7 +426,7 @@ func BlankUser() *User {
|
|||
|
||||
// TODO: Write unit tests for this
|
||||
func BuildProfileURL(slug string, uid int) string {
|
||||
if slug == "" {
|
||||
if slug == "" || !Config.BuildSlugs {
|
||||
return "/user/" + strconv.Itoa(uid)
|
||||
}
|
||||
return "/user/" + slug + "." + strconv.Itoa(uid)
|
||||
|
|
|
@ -184,6 +184,10 @@ func ConvertFriendlyUnit(num int) (int, string) {
|
|||
// TODO: Make slugs optional for certain languages across the entirety of Gosora?
|
||||
// TODO: Let plugins replace NameToSlug and the URL building logic with their own
|
||||
func NameToSlug(name string) (slug string) {
|
||||
// TODO: Do we want this reliant on config file flags? This might complicate tests and oddball uses
|
||||
if !Config.BuildSlugs {
|
||||
return ""
|
||||
}
|
||||
name = strings.TrimSpace(name)
|
||||
name = strings.Replace(name, " ", " ", -1)
|
||||
|
||||
|
@ -204,12 +208,25 @@ func NameToSlug(name string) (slug string) {
|
|||
}
|
||||
|
||||
// TODO: Write a test for this
|
||||
func WeakPassword(password string) error {
|
||||
if len(password) < 8 {
|
||||
return errors.New("your password needs to be at-least eight characters long")
|
||||
func WeakPassword(password string, username string, email string) error {
|
||||
lowPassword := strings.ToLower(password)
|
||||
switch {
|
||||
case password == "":
|
||||
return errors.New("You didn't put in a password.")
|
||||
case strings.Contains(lowPassword, strings.ToLower(username)) && len(username) > 3:
|
||||
return errors.New("You can't use your username in your password.")
|
||||
case strings.Contains(lowPassword, strings.ToLower(email)):
|
||||
return errors.New("You can't use your email in your password.")
|
||||
case len(password) < 8:
|
||||
return errors.New("Your password needs to be at-least eight characters long")
|
||||
}
|
||||
|
||||
if strings.Contains(lowPassword, "test") || /*strings.Contains(password,"123456") || */ strings.Contains(password, "123") || strings.Contains(lowPassword, "password") || strings.Contains(lowPassword, "qwerty") || strings.Contains(lowPassword, "fuck") || strings.Contains(lowPassword, "love") {
|
||||
return errors.New("You may not have 'test', '123', 'password', 'qwerty', 'love' or 'fuck' in your password")
|
||||
}
|
||||
|
||||
var charMap = make(map[rune]int)
|
||||
var numbers /*letters, */, symbols, upper, lower int
|
||||
var numbers, symbols, upper, lower int
|
||||
for _, char := range password {
|
||||
charItem, ok := charMap[char]
|
||||
if ok {
|
||||
|
@ -220,7 +237,6 @@ func WeakPassword(password string) error {
|
|||
charMap[char] = charItem
|
||||
|
||||
if unicode.IsLetter(char) {
|
||||
//letters++
|
||||
if unicode.IsUpper(char) {
|
||||
upper++
|
||||
} else {
|
||||
|
@ -233,25 +249,22 @@ func WeakPassword(password string) error {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Disable the linter on these and fix up the grammar
|
||||
if numbers == 0 {
|
||||
return errors.New("you don't have any numbers in your password")
|
||||
return errors.New("You don't have any numbers in your password")
|
||||
}
|
||||
/*if letters == 0 {
|
||||
return errors.New("You don't have any letters in your password.")
|
||||
}*/
|
||||
if upper == 0 {
|
||||
return errors.New("you don't have any uppercase characters in your password")
|
||||
return errors.New("You don't have any uppercase characters in your password")
|
||||
}
|
||||
if lower == 0 {
|
||||
return errors.New("you don't have any lowercase characters in your password")
|
||||
return errors.New("You don't have any lowercase characters in your password")
|
||||
}
|
||||
if (len(password) / 2) > len(charMap) {
|
||||
return errors.New("you don't have enough unique characters in your password")
|
||||
}
|
||||
|
||||
if strings.Contains(strings.ToLower(password), "test") || /*strings.Contains(strings.ToLower(password),"123456") || */ strings.Contains(strings.ToLower(password), "123") || strings.Contains(strings.ToLower(password), "password") || strings.Contains(strings.ToLower(password), "qwerty") {
|
||||
return errors.New("you may not have 'test', '123', 'password' or 'qwerty' in your password")
|
||||
if len(password) < 18 {
|
||||
if (len(password) / 2) > len(charMap) {
|
||||
return errors.New("You don't have enough unique characters in your password")
|
||||
}
|
||||
} else if (len(password) / 3) > len(charMap) {
|
||||
// Be a little lenient on the number of unique characters for long passwords
|
||||
return errors.New("You don't have enough unique characters in your password")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -372,7 +385,7 @@ func GetLevels(maxLevel int) []float64 {
|
|||
}
|
||||
|
||||
func BuildSlug(slug string, id int) string {
|
||||
if slug == "" {
|
||||
if slug == "" || !Config.BuildSlugs {
|
||||
return strconv.Itoa(id)
|
||||
}
|
||||
return slug + "." + strconv.Itoa(id)
|
||||
|
|
|
@ -359,8 +359,8 @@ func RouteMemberList(w http.ResponseWriter, r *http.Request, user common.User) c
|
|||
pi := MemberListPage{"Guild Member List", user, headerVars, guildMembers, guildItem, 0, 0}
|
||||
// A plugin with plugins. Pluginception!
|
||||
if common.RunPreRenderHook("pre_render_guilds_member_list", w, r, &user, &pi) {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err = common.RunThemeTemplate(headerVars.Theme.Name, "guilds_member_list", pi, w)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -379,10 +379,10 @@ func UnattachForum(fid int) error {
|
|||
}
|
||||
|
||||
func BuildGuildURL(slug string, id int) string {
|
||||
if slug == "" {
|
||||
return "/guild/" + slug + "." + strconv.Itoa(id)
|
||||
if slug == "" || !common.Config.BuildSlugs {
|
||||
return "/guild/" + strconv.Itoa(id)
|
||||
}
|
||||
return "/guild/" + strconv.Itoa(id)
|
||||
return "/guild/" + slug + "." + strconv.Itoa(id)
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"strconv"
|
||||
"sync"
|
||||
"errors"
|
||||
"os"
|
||||
"net/http"
|
||||
|
||||
"./common"
|
||||
|
@ -491,11 +492,17 @@ func (writ *WriterIntercept) GetCode() int {
|
|||
type GenRouter struct {
|
||||
UploadHandler func(http.ResponseWriter, *http.Request)
|
||||
extraRoutes map[string]func(http.ResponseWriter, *http.Request, common.User) common.RouteError
|
||||
requestLogger *log.Logger
|
||||
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func NewGenRouter(uploads http.Handler) *GenRouter {
|
||||
func NewGenRouter(uploads http.Handler) (*GenRouter, error) {
|
||||
f, err := os.OpenFile("./logs/requests.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &GenRouter{
|
||||
UploadHandler: func(w http.ResponseWriter, req *http.Request) {
|
||||
writ := NewWriterIntercept(w)
|
||||
|
@ -506,7 +513,8 @@ func NewGenRouter(uploads http.Handler) *GenRouter {
|
|||
}
|
||||
},
|
||||
extraRoutes: make(map[string]func(http.ResponseWriter, *http.Request, common.User) common.RouteError),
|
||||
}
|
||||
requestLogger: log.New(f, "", log.LstdFlags),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (router *GenRouter) handleError(err common.RouteError, w http.ResponseWriter, r *http.Request, user common.User) {
|
||||
|
@ -554,7 +562,7 @@ func (router *GenRouter) DumpRequest(req *http.Request, prepend string) {
|
|||
}
|
||||
}
|
||||
|
||||
log.Print(prepend +
|
||||
router.requestLogger.Print(prepend +
|
||||
"\nUA: " + router.StripNewlines(req.UserAgent()) + "\n" +
|
||||
"Method: " + router.StripNewlines(req.Method) + "\n" + heads +
|
||||
"req.Host: " + router.StripNewlines(req.Host) + "\n" +
|
||||
|
@ -564,8 +572,11 @@ func (router *GenRouter) DumpRequest(req *http.Request, prepend string) {
|
|||
"req.RemoteAddr: " + req.RemoteAddr + "\n")
|
||||
}
|
||||
|
||||
func (router *GenRouter) SuspiciousRequest(req *http.Request) {
|
||||
router.DumpRequest(req,"Suspicious Request")
|
||||
func (router *GenRouter) SuspiciousRequest(req *http.Request, prepend string) {
|
||||
if prepend != "" {
|
||||
prepend += "\n"
|
||||
}
|
||||
router.DumpRequest(req,prepend+"Suspicious Request")
|
||||
counters.AgentViewCounter.Bump(27)
|
||||
}
|
||||
|
||||
|
@ -600,14 +611,14 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
// TODO: Cover more suspicious strings and at a lower layer than this
|
||||
for _, char := range req.URL.Path {
|
||||
if char != '&' && !(char > 44 && char < 58) && char != '=' && char != '?' && !(char > 64 && char < 91) && char != '\\' && char != '_' && !(char > 96 && char < 123) {
|
||||
router.SuspiciousRequest(req)
|
||||
router.SuspiciousRequest(req,"")
|
||||
break
|
||||
}
|
||||
}
|
||||
lowerPath := strings.ToLower(req.URL.Path)
|
||||
// TODO: Flag any requests which has a dot with anything but a number after that
|
||||
if strings.Contains(req.URL.Path,"..") || strings.Contains(req.URL.Path,"--") || strings.Contains(lowerPath,".php") || strings.Contains(lowerPath,".asp") || strings.Contains(lowerPath,".cgi") || strings.Contains(lowerPath,".py") || strings.Contains(lowerPath,".sql") || strings.Contains(lowerPath,".action") {
|
||||
router.SuspiciousRequest(req)
|
||||
router.SuspiciousRequest(req,"")
|
||||
}
|
||||
|
||||
var prefix, extraData string
|
||||
|
@ -630,7 +641,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
if common.Dev.SuperDebug {
|
||||
log.Print("before PreRoute")
|
||||
router.requestLogger.Print("before PreRoute")
|
||||
}
|
||||
|
||||
// Track the user agents. Unfortunately, everyone pretends to be Mozilla, so this'll be a little less efficient than I would like.
|
||||
|
@ -676,9 +687,9 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
// TODO: Test this
|
||||
items = items[:0]
|
||||
indices = indices[:0]
|
||||
router.SuspiciousRequest(req)
|
||||
log.Print("UA Buffer: ", buffer)
|
||||
log.Print("UA Buffer String: ", string(buffer))
|
||||
router.SuspiciousRequest(req,"")
|
||||
router.requestLogger.Print("UA Buffer: ", buffer)
|
||||
router.requestLogger.Print("UA Buffer String: ", string(buffer))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -695,7 +706,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
}
|
||||
if common.Dev.SuperDebug {
|
||||
log.Print("parsed agent: ", agent)
|
||||
router.requestLogger.Print("parsed agent: ", agent)
|
||||
}
|
||||
|
||||
var os string
|
||||
|
@ -717,8 +728,8 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
os = "unknown"
|
||||
}
|
||||
if common.Dev.SuperDebug {
|
||||
log.Print("os: ", os)
|
||||
log.Printf("items: %+v\n",items)
|
||||
router.requestLogger.Print("os: ", os)
|
||||
router.requestLogger.Printf("items: %+v\n",items)
|
||||
}
|
||||
|
||||
// Special handling
|
||||
|
@ -737,7 +748,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
agent = "internetexplorer"
|
||||
}
|
||||
case "zgrab":
|
||||
router.SuspiciousRequest(req)
|
||||
router.SuspiciousRequest(req,"Vulnerability Scanner")
|
||||
}
|
||||
|
||||
if agent == "" {
|
||||
|
@ -783,8 +794,9 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
if common.Dev.SuperDebug {
|
||||
log.Print("after PreRoute")
|
||||
log.Print("routeMapEnum: ", routeMapEnum)
|
||||
router.requestLogger.Print(
|
||||
"after PreRoute\n" +
|
||||
"routeMapEnum: ", routeMapEnum)
|
||||
}
|
||||
|
||||
var err common.RouteError
|
||||
|
@ -1801,7 +1813,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
handle, ok := RouteMap[common.Config.DefaultRoute]
|
||||
if !ok {
|
||||
// TODO: Make this a startup error not a runtime one
|
||||
log.Print("Unable to find the default route")
|
||||
router.requestLogger.Print("Unable to find the default route")
|
||||
common.NotFound(w,req,nil)
|
||||
return
|
||||
}
|
||||
|
@ -1824,10 +1836,11 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO: Log all bad routes for the admin to figure out where users are going wrong?
|
||||
lowerPath := strings.ToLower(req.URL.Path)
|
||||
if strings.Contains(lowerPath,"admin") || strings.Contains(lowerPath,"sql") || strings.Contains(lowerPath,"manage") || strings.Contains(lowerPath,"//") || strings.Contains(lowerPath,"\\\\") || strings.Contains(lowerPath,"wp") || strings.Contains(lowerPath,"wordpress") || strings.Contains(lowerPath,"config") || strings.Contains(lowerPath,"setup") || strings.Contains(lowerPath,"install") || strings.Contains(lowerPath,"update") || strings.Contains(lowerPath,"php") {
|
||||
router.SuspiciousRequest(req)
|
||||
router.SuspiciousRequest(req,"Bad Route")
|
||||
} else {
|
||||
router.DumpRequest(req,"Bad Route")
|
||||
}
|
||||
counters.RouteViewCounter.Bump(104)
|
||||
common.NotFound(w,req,nil)
|
||||
|
|
|
@ -78,7 +78,10 @@ func gloinit() (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
router = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
router, err = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gloinited = true
|
||||
return nil
|
||||
}
|
||||
|
@ -142,13 +145,17 @@ func BenchmarkTopicAdminRouteParallel(b *testing.B) {
|
|||
|
||||
func BenchmarkTopicAdminRouteParallelWithRouter(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
var err error
|
||||
if !gloinited {
|
||||
err := gloinit()
|
||||
err = gloinit()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
router = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
router, err = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
prev := common.Dev.DebugMode
|
||||
prev2 := common.Dev.SuperDebug
|
||||
common.Dev.DebugMode = false
|
||||
|
@ -260,13 +267,17 @@ func BenchmarkTopicGuestRouteParallelDebugMode(b *testing.B) {
|
|||
|
||||
func BenchmarkTopicGuestRouteParallelWithRouter(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
var err error
|
||||
if !gloinited {
|
||||
err := gloinit()
|
||||
err = gloinit()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
router = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
router, err = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
prev := common.Dev.DebugMode
|
||||
prev2 := common.Dev.SuperDebug
|
||||
common.Dev.DebugMode = false
|
||||
|
@ -301,13 +312,17 @@ func BenchmarkTopicGuestRouteParallelWithRouter(b *testing.B) {
|
|||
|
||||
func BenchmarkBadRouteGuestRouteParallelWithRouter(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
var err error
|
||||
if !gloinited {
|
||||
err := gloinit()
|
||||
err = gloinit()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
router = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
router, err = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
prev := common.Dev.DebugMode
|
||||
prev2 := common.Dev.SuperDebug
|
||||
common.Dev.DebugMode = false
|
||||
|
@ -330,13 +345,17 @@ func BenchmarkBadRouteGuestRouteParallelWithRouter(b *testing.B) {
|
|||
|
||||
func BenchmarkTopicsGuestRouteParallelWithRouter(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
var err error
|
||||
if !gloinited {
|
||||
err := gloinit()
|
||||
err = gloinit()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
router = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
router, err = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
prev := common.Dev.DebugMode
|
||||
prev2 := common.Dev.SuperDebug
|
||||
common.Dev.DebugMode = false
|
||||
|
@ -363,13 +382,17 @@ func BenchmarkTopicsGuestRouteParallelWithRouter(b *testing.B) {
|
|||
|
||||
func BenchmarkForumsGuestRouteParallelWithRouter(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
var err error
|
||||
if !gloinited {
|
||||
err := gloinit()
|
||||
err = gloinit()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
router = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
router, err = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
prev := common.Dev.DebugMode
|
||||
prev2 := common.Dev.SuperDebug
|
||||
common.Dev.DebugMode = false
|
||||
|
@ -396,13 +419,17 @@ func BenchmarkForumsGuestRouteParallelWithRouter(b *testing.B) {
|
|||
|
||||
func BenchmarkForumGuestRouteParallelWithRouter(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
var err error
|
||||
if !gloinited {
|
||||
err := gloinit()
|
||||
err = gloinit()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
router = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
router, err = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
prev := common.Dev.DebugMode
|
||||
prev2 := common.Dev.SuperDebug
|
||||
common.Dev.DebugMode = false
|
||||
|
|
|
@ -31,6 +31,8 @@ go get -u github.com/fsnotify/fsnotify
|
|||
echo "Installing Go Git"
|
||||
go get -u gopkg.in/src-d/go-git.v4/...
|
||||
|
||||
echo "Installing GopherJS"
|
||||
go get -u github.com/gopherjs/gopherjs
|
||||
|
||||
echo "Building the installer"
|
||||
cd ./install
|
||||
|
|
|
@ -92,6 +92,13 @@ if %errorlevel% neq 0 (
|
|||
exit /b %errorlevel%
|
||||
)
|
||||
|
||||
echo Installing GopherJS
|
||||
go get -u github.com/gopherjs/gopherjs
|
||||
if %errorlevel% neq 0 (
|
||||
pause
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
|
||||
|
||||
echo Building the installer
|
||||
go generate
|
||||
|
|
|
@ -148,6 +148,7 @@ func init() {
|
|||
common.Config.StaffCSS = "staff_post"
|
||||
common.Config.DefaultForum = 2
|
||||
common.Config.MinifyTemplates = true
|
||||
common.Config.BuildSlugs = true
|
||||
common.Config.ServerCount = 1 // Experimental: Enable Cross-Server Synchronisation and several other features
|
||||
|
||||
//common.Config.Noavatar = "https://api.adorable.io/avatars/{width}/{id}@{site_url}.png"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
This file is here so that Git will include this folder in the repository.
|
7
main.go
7
main.go
|
@ -182,7 +182,7 @@ func main() {
|
|||
|
||||
// TODO: Have a file for each run with the time/date the server started as the file name?
|
||||
// TODO: Log panics with recover()
|
||||
f, err := os.OpenFile("./ops.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755)
|
||||
f, err := os.OpenFile("./logs/ops.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -367,7 +367,10 @@ func main() {
|
|||
}()
|
||||
|
||||
log.Print("Initialising the router")
|
||||
router = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
router, err = NewGenRouter(http.FileServer(http.Dir("./uploads")))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Print("Initialising the plugins")
|
||||
common.InitPlugins()
|
||||
|
|
|
@ -822,6 +822,7 @@ func TestProfileReplyStore(t *testing.T) {
|
|||
func TestSlugs(t *testing.T) {
|
||||
var res string
|
||||
var msgList []MEPair
|
||||
common.Config.BuildSlugs = true // Flip this switch, otherwise all the tests will fail
|
||||
|
||||
msgList = addMEPair(msgList, "Unknown", "unknown")
|
||||
msgList = addMEPair(msgList, "Unknown2", "unknown2")
|
||||
|
|
|
@ -2567,10 +2567,24 @@ func routePanelDebug(w http.ResponseWriter, r *http.Request, user common.User) c
|
|||
return ferr
|
||||
}
|
||||
|
||||
uptime := "..."
|
||||
var uptime string
|
||||
upDuration := time.Since(startTime)
|
||||
hours := int(upDuration.Hours())
|
||||
minutes := int(upDuration.Minutes())
|
||||
if hours > 24 {
|
||||
days := hours / 24
|
||||
hours -= days * 24
|
||||
uptime += strconv.Itoa(days) + "d"
|
||||
uptime += strconv.Itoa(hours) + "h"
|
||||
} else if hours >= 1 {
|
||||
uptime += strconv.Itoa(hours) + "h"
|
||||
}
|
||||
uptime += strconv.Itoa(minutes) + "m"
|
||||
|
||||
dbStats := db.Stats()
|
||||
openConnCount := dbStats.OpenConnections
|
||||
// Disk I/O?
|
||||
// TODO: Fetch the adapter from Builder rather than getting it from a global?
|
||||
|
||||
pi := common.PanelDebugPage{common.GetTitlePhrase("panel_debug"), user, headerVars, stats, "debug", uptime, openConnCount, dbAdapter}
|
||||
return panelRenderTemplate("panel_debug", w, r, user, &pi)
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
//"log"
|
||||
//"fmt"
|
||||
"bytes"
|
||||
|
||||
//"strings"
|
||||
"math/rand"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
@ -215,9 +211,6 @@ func bbcodeFullParse(msg string) string {
|
|||
|
||||
msgbytes := []byte(msg)
|
||||
msgbytes = append(msgbytes, common.SpaceGap...)
|
||||
//log.Print("BBCode Simple Pre:","`"+string(msgbytes)+"`")
|
||||
//log.Print("----")
|
||||
|
||||
for i := 0; i < len(msgbytes); i++ {
|
||||
if msgbytes[i] == '[' {
|
||||
if msgbytes[i+2] != ']' {
|
||||
|
@ -248,12 +241,6 @@ func bbcodeFullParse(msg string) string {
|
|||
hasC = false
|
||||
i += 7
|
||||
}
|
||||
//if msglen >= (i+6) {
|
||||
// log.Print("boo")
|
||||
// log.Print(msglen)
|
||||
// log.Print(i+6)
|
||||
// log.Print(string(msgbytes[i:i+6]))
|
||||
//}
|
||||
complexBbc = true
|
||||
}
|
||||
} else {
|
||||
|
@ -261,9 +248,6 @@ func bbcodeFullParse(msg string) string {
|
|||
hasC = true
|
||||
i += 6
|
||||
}
|
||||
//if msglen >= (i+5) {
|
||||
// log.Print("boo2: ", string(msgbytes[i:i+5]))
|
||||
//}
|
||||
complexBbc = true
|
||||
}
|
||||
} else if !hasC {
|
||||
|
@ -314,8 +298,6 @@ func bbcodeFullParse(msg string) string {
|
|||
i := 0
|
||||
var start, lastTag int
|
||||
var outbytes []byte
|
||||
//log.Print("BBCode Pre:","`"+string(msgbytes)+"`")
|
||||
//log.Print("----")
|
||||
for ; i < len(msgbytes); i++ {
|
||||
if msgbytes[i] == '[' {
|
||||
if msgbytes[i+1] == 'u' {
|
||||
|
@ -330,18 +312,15 @@ func bbcodeFullParse(msg string) string {
|
|||
}
|
||||
}
|
||||
}
|
||||
//log.Print("Outbytes:",`"`+string(outbytes)+`"`)
|
||||
if lastTag != i {
|
||||
outbytes = append(outbytes, msgbytes[lastTag:]...)
|
||||
}
|
||||
|
||||
if len(outbytes) != 0 {
|
||||
//log.Print("BBCode Post:",`"`+string(outbytes[0:len(outbytes) - 10])+`"`)
|
||||
msg = string(outbytes[0 : len(outbytes)-10])
|
||||
} else {
|
||||
msg = string(msgbytes[0 : len(msgbytes)-10])
|
||||
}
|
||||
//log.Print("----")
|
||||
|
||||
//msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>")
|
||||
msg = bbcodeURLLabel.ReplaceAllString(msg, "<a href='$1$2//$3' rel='nofollow'>$4</i>")
|
||||
|
@ -359,11 +338,7 @@ func bbcodeParseURL(i int, start int, lastTag int, msgbytes []byte, outbytes []b
|
|||
outbytes = append(outbytes, msgbytes[lastTag:i]...)
|
||||
i = start
|
||||
i += common.PartialURLBytesLen(msgbytes[start:])
|
||||
//log.Print("Partial Bytes: ", string(msgbytes[start:]))
|
||||
//log.Print("-----")
|
||||
if !bytes.Equal(msgbytes[i:i+6], []byte("[/url]")) {
|
||||
//log.Print("Invalid Bytes: ", string(msgbytes[i:i+6]))
|
||||
//log.Print("-----")
|
||||
outbytes = append(outbytes, common.InvalidURL...)
|
||||
return i, start, lastTag, outbytes
|
||||
}
|
||||
|
@ -416,7 +391,6 @@ func bbcodeParseRand(i int, start int, lastTag int, msgbytes []byte, outbytes []
|
|||
}
|
||||
|
||||
outbytes = append(outbytes, dat...)
|
||||
//log.Print("Outputted the random number")
|
||||
i += 7
|
||||
lastTag = i
|
||||
return i, start, lastTag, outbytes
|
||||
|
|
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
//import "fmt"
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"./common"
|
||||
|
@ -51,7 +50,6 @@ func markdownParse(msg string) string {
|
|||
if msg[len(msg)-1] == ' ' {
|
||||
msg = msg[:len(msg)-1]
|
||||
}
|
||||
log.Print("final msg: ", msg)
|
||||
return msg
|
||||
}
|
||||
|
||||
|
@ -66,12 +64,6 @@ func _markdownParse(msg string, n int) string {
|
|||
common.DebugLogf("Initial Message: %+v\n", strings.Replace(msg, "\r", "\\r", -1))
|
||||
|
||||
for index := 0; index < len(msg); index++ {
|
||||
//log.Print("--OUTER MARKDOWN LOOP START--")
|
||||
//log.Print("index: ", index)
|
||||
//log.Print("msg[index]: ", msg[index])
|
||||
//log.Print("string(msg[index]): ", string(msg[index]))
|
||||
//log.Printf("--OUTER MARKDOWN LOOP END--\n\n")
|
||||
|
||||
switch msg[index] {
|
||||
// TODO: Do something slightly less hacky for skipping URLs
|
||||
case '/':
|
||||
|
@ -131,95 +123,53 @@ func _markdownParse(msg string, n int) string {
|
|||
lastElement = index
|
||||
index--
|
||||
case '*':
|
||||
//log.Print("------")
|
||||
//log.Print("[]byte(msg): ", []byte(msg))
|
||||
//log.Print("len(msg): ", len(msg))
|
||||
//log.Print("start index: ", index)
|
||||
//log.Print("start msg[index]: ", msg[index])
|
||||
//log.Print("start string(msg[index]): ", string(msg[index]))
|
||||
//log.Print("start []byte(msg[:index]): ", []byte(msg[:index]))
|
||||
|
||||
var startIndex = index
|
||||
var italic = true
|
||||
var bold = false
|
||||
if (index + 2) < len(msg) {
|
||||
//log.Print("start index + 1: ", index + 1)
|
||||
//log.Print("start msg[index]: ", msg[index + 1])
|
||||
//log.Print("start string(msg[index]): ", string(msg[index + 1]))
|
||||
if msg[index+1] == '*' {
|
||||
//log.Print("two asterisks")
|
||||
bold = true
|
||||
index++
|
||||
if msg[index+1] != '*' {
|
||||
italic = false
|
||||
} else {
|
||||
//log.Print("three asterisks")
|
||||
index++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//log.Print("lastElement: ", lastElement)
|
||||
//log.Print("startIndex: ", startIndex)
|
||||
//log.Print("msg[startIndex]: ", msg[startIndex])
|
||||
//log.Print("string(msg[startIndex]): ", string(msg[startIndex]))
|
||||
|
||||
//log.Print("preabrupt index: ", index)
|
||||
//log.Print("preabrupt msg[index]: ", msg[index])
|
||||
//log.Print("preabrupt string(msg[index]): ", string(msg[index]))
|
||||
//log.Print("preabrupt []byte(msg[:index]): ", []byte(msg[:index]))
|
||||
//log.Print("preabrupt msg[:index]: ", msg[:index])
|
||||
|
||||
// Does the string terminate abruptly?
|
||||
if (index + 1) >= len(msg) {
|
||||
break
|
||||
}
|
||||
|
||||
index++
|
||||
|
||||
//log.Print("preskip index: ", index)
|
||||
//log.Print("preskip msg[index]: ", msg[index])
|
||||
//log.Print("preskip string(msg[index]): ", string(msg[index]))
|
||||
index = markdownSkipUntilAsterisk(msg, index)
|
||||
|
||||
if index >= len(msg) {
|
||||
break
|
||||
}
|
||||
|
||||
//log.Print("index: ", index)
|
||||
//log.Print("[]byte(msg[:index]): ", []byte(msg[:index]))
|
||||
//log.Print("msg[index]: ", msg[index])
|
||||
|
||||
sIndex := startIndex
|
||||
lIndex := index
|
||||
if bold && italic {
|
||||
//log.Print("bold & italic final code")
|
||||
if (index + 3) >= len(msg) {
|
||||
//log.Print("unclosed markdown element @ exit element")
|
||||
outbytes = append(outbytes, msg[lastElement:startIndex]...)
|
||||
//outbytes = append(outbytes, markdownUnclosedElement...)
|
||||
lastElement = startIndex
|
||||
break
|
||||
}
|
||||
index += 3
|
||||
sIndex += 3
|
||||
} else if bold {
|
||||
//log.Print("bold final code")
|
||||
if (index + 2) >= len(msg) {
|
||||
//log.Print("true unclosed markdown element @ exit element")
|
||||
outbytes = append(outbytes, msg[lastElement:startIndex]...)
|
||||
//outbytes = append(outbytes, markdownUnclosedElement...)
|
||||
lastElement = startIndex
|
||||
break
|
||||
}
|
||||
index += 2
|
||||
sIndex += 2
|
||||
} else {
|
||||
//log.Print("italic final code")
|
||||
if (index + 1) >= len(msg) {
|
||||
//log.Print("true unclosed markdown element @ exit element")
|
||||
outbytes = append(outbytes, msg[lastElement:startIndex]...)
|
||||
//outbytes = append(outbytes, markdownUnclosedElement...)
|
||||
lastElement = startIndex
|
||||
break
|
||||
}
|
||||
|
@ -227,38 +177,18 @@ func _markdownParse(msg string, n int) string {
|
|||
sIndex++
|
||||
}
|
||||
|
||||
//log.Print("sIndex: ", sIndex)
|
||||
//log.Print("lIndex: ", lIndex)
|
||||
if lIndex <= sIndex {
|
||||
//log.Print("unclosed markdown element @ lIndex <= sIndex")
|
||||
outbytes = append(outbytes, msg[lastElement:startIndex]...)
|
||||
//outbytes = append(outbytes, markdownUnclosedElement...)
|
||||
lastElement = startIndex
|
||||
break
|
||||
}
|
||||
|
||||
if sIndex < 0 || lIndex < 0 {
|
||||
//log.Print("unclosed markdown element @ sIndex < 0 || lIndex < 0")
|
||||
outbytes = append(outbytes, msg[lastElement:startIndex]...)
|
||||
//outbytes = append(outbytes, markdownUnclosedElement...)
|
||||
lastElement = startIndex
|
||||
break
|
||||
}
|
||||
|
||||
//log.Print("final sIndex: ", sIndex)
|
||||
//log.Print("final lIndex: ",lIndex)
|
||||
//log.Print("final index: ", index)
|
||||
//log.Print("final msg[index]: ", msg[index])
|
||||
//log.Print("final string(msg[index]): ", string(msg[index]))
|
||||
|
||||
//log.Print("final msg[sIndex]: ", msg[sIndex])
|
||||
//log.Print("final string(msg[sIndex]): ", string(msg[sIndex]))
|
||||
//log.Print("final msg[lIndex]: ", msg[lIndex])
|
||||
//log.Print("final string(msg[lIndex]): ", string(msg[lIndex]))
|
||||
|
||||
//log.Print("[]byte(msg[:sIndex]): ", []byte(msg[:sIndex]))
|
||||
//log.Print("[]byte(msg[:lIndex]): ", []byte(msg[:lIndex]))
|
||||
|
||||
outbytes = append(outbytes, msg[lastElement:startIndex]...)
|
||||
|
||||
if bold {
|
||||
|
@ -292,17 +222,13 @@ func _markdownParse(msg string, n int) string {
|
|||
//case 10: // newline
|
||||
}
|
||||
}
|
||||
//log.Print("exit message loop")
|
||||
|
||||
if len(outbytes) == 0 {
|
||||
return msg
|
||||
//return msg[:len(msg)-1]
|
||||
} else if lastElement < (len(msg) - 1) {
|
||||
msg = string(outbytes) + msg[lastElement:]
|
||||
return msg
|
||||
//return msg[:len(msg)-1]
|
||||
}
|
||||
//return string(outbytes[:len(outbytes)-1])
|
||||
return string(outbytes)
|
||||
}
|
||||
|
||||
|
|
|
@ -379,6 +379,19 @@ func createTables(adapter qgen.Adapter) error {
|
|||
[]qgen.DBTableKey{},
|
||||
)
|
||||
|
||||
/*
|
||||
qgen.Install.CreateTable("registration_logs", "", "",
|
||||
[]qgen.DBTableColumn{
|
||||
qgen.DBTableColumn{"username", "varchar", 100, false, false, ""},
|
||||
qgen.DBTableColumn{"email", "varchar", 100, false, false, ""},
|
||||
qgen.DBTableColumn{"failureReason", "varchar", 100, false, false, ""},
|
||||
qgen.DBTableColumn{"success", "int", 0, false, false, "0"}, // Did this attempt succeed?
|
||||
qgen.DBTableColumn{"doneAt", "createdAt", 0, false, false, ""},
|
||||
},
|
||||
[]qgen.DBTableKey{},
|
||||
)
|
||||
*/
|
||||
|
||||
qgen.Install.CreateTable("moderation_logs", "", "",
|
||||
[]qgen.DBTableColumn{
|
||||
qgen.DBTableColumn{"action", "varchar", 100, false, false, ""},
|
||||
|
|
|
@ -226,6 +226,7 @@ import (
|
|||
"strconv"
|
||||
"sync"
|
||||
"errors"
|
||||
"os"
|
||||
"net/http"
|
||||
|
||||
"./common"
|
||||
|
@ -331,11 +332,17 @@ func (writ *WriterIntercept) GetCode() int {
|
|||
type GenRouter struct {
|
||||
UploadHandler func(http.ResponseWriter, *http.Request)
|
||||
extraRoutes map[string]func(http.ResponseWriter, *http.Request, common.User) common.RouteError
|
||||
requestLogger *log.Logger
|
||||
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func NewGenRouter(uploads http.Handler) *GenRouter {
|
||||
func NewGenRouter(uploads http.Handler) (*GenRouter, error) {
|
||||
f, err := os.OpenFile("./logs/requests.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &GenRouter{
|
||||
UploadHandler: func(w http.ResponseWriter, req *http.Request) {
|
||||
writ := NewWriterIntercept(w)
|
||||
|
@ -346,7 +353,8 @@ func NewGenRouter(uploads http.Handler) *GenRouter {
|
|||
}
|
||||
},
|
||||
extraRoutes: make(map[string]func(http.ResponseWriter, *http.Request, common.User) common.RouteError),
|
||||
}
|
||||
requestLogger: log.New(f, "", log.LstdFlags),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (router *GenRouter) handleError(err common.RouteError, w http.ResponseWriter, r *http.Request, user common.User) {
|
||||
|
@ -394,7 +402,7 @@ func (router *GenRouter) DumpRequest(req *http.Request, prepend string) {
|
|||
}
|
||||
}
|
||||
|
||||
log.Print(prepend +
|
||||
router.requestLogger.Print(prepend +
|
||||
"\nUA: " + router.StripNewlines(req.UserAgent()) + "\n" +
|
||||
"Method: " + router.StripNewlines(req.Method) + "\n" + heads +
|
||||
"req.Host: " + router.StripNewlines(req.Host) + "\n" +
|
||||
|
@ -404,8 +412,11 @@ func (router *GenRouter) DumpRequest(req *http.Request, prepend string) {
|
|||
"req.RemoteAddr: " + req.RemoteAddr + "\n")
|
||||
}
|
||||
|
||||
func (router *GenRouter) SuspiciousRequest(req *http.Request) {
|
||||
router.DumpRequest(req,"Suspicious Request")
|
||||
func (router *GenRouter) SuspiciousRequest(req *http.Request, prepend string) {
|
||||
if prepend != "" {
|
||||
prepend += "\n"
|
||||
}
|
||||
router.DumpRequest(req,prepend+"Suspicious Request")
|
||||
counters.AgentViewCounter.Bump({{.AllAgentMap.suspicious}})
|
||||
}
|
||||
|
||||
|
@ -440,14 +451,14 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
// TODO: Cover more suspicious strings and at a lower layer than this
|
||||
for _, char := range req.URL.Path {
|
||||
if char != '&' && !(char > 44 && char < 58) && char != '=' && char != '?' && !(char > 64 && char < 91) && char != '\\' && char != '_' && !(char > 96 && char < 123) {
|
||||
router.SuspiciousRequest(req)
|
||||
router.SuspiciousRequest(req,"")
|
||||
break
|
||||
}
|
||||
}
|
||||
lowerPath := strings.ToLower(req.URL.Path)
|
||||
// TODO: Flag any requests which has a dot with anything but a number after that
|
||||
if strings.Contains(req.URL.Path,"..") || strings.Contains(req.URL.Path,"--") || strings.Contains(lowerPath,".php") || strings.Contains(lowerPath,".asp") || strings.Contains(lowerPath,".cgi") || strings.Contains(lowerPath,".py") || strings.Contains(lowerPath,".sql") || strings.Contains(lowerPath,".action") {
|
||||
router.SuspiciousRequest(req)
|
||||
router.SuspiciousRequest(req,"")
|
||||
}
|
||||
|
||||
var prefix, extraData string
|
||||
|
@ -470,7 +481,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
if common.Dev.SuperDebug {
|
||||
log.Print("before PreRoute")
|
||||
router.requestLogger.Print("before PreRoute")
|
||||
}
|
||||
|
||||
// Track the user agents. Unfortunately, everyone pretends to be Mozilla, so this'll be a little less efficient than I would like.
|
||||
|
@ -516,9 +527,9 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
// TODO: Test this
|
||||
items = items[:0]
|
||||
indices = indices[:0]
|
||||
router.SuspiciousRequest(req)
|
||||
log.Print("UA Buffer: ", buffer)
|
||||
log.Print("UA Buffer String: ", string(buffer))
|
||||
router.SuspiciousRequest(req,"")
|
||||
router.requestLogger.Print("UA Buffer: ", buffer)
|
||||
router.requestLogger.Print("UA Buffer String: ", string(buffer))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -535,7 +546,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
}
|
||||
if common.Dev.SuperDebug {
|
||||
log.Print("parsed agent: ", agent)
|
||||
router.requestLogger.Print("parsed agent: ", agent)
|
||||
}
|
||||
|
||||
var os string
|
||||
|
@ -557,8 +568,8 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
os = "unknown"
|
||||
}
|
||||
if common.Dev.SuperDebug {
|
||||
log.Print("os: ", os)
|
||||
log.Printf("items: %+v\n",items)
|
||||
router.requestLogger.Print("os: ", os)
|
||||
router.requestLogger.Printf("items: %+v\n",items)
|
||||
}
|
||||
|
||||
// Special handling
|
||||
|
@ -577,7 +588,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
agent = "internetexplorer"
|
||||
}
|
||||
case "zgrab":
|
||||
router.SuspiciousRequest(req)
|
||||
router.SuspiciousRequest(req,"Vulnerability Scanner")
|
||||
}
|
||||
|
||||
if agent == "" {
|
||||
|
@ -623,8 +634,9 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
if common.Dev.SuperDebug {
|
||||
log.Print("after PreRoute")
|
||||
log.Print("routeMapEnum: ", routeMapEnum)
|
||||
router.requestLogger.Print(
|
||||
"after PreRoute\n" +
|
||||
"routeMapEnum: ", routeMapEnum)
|
||||
}
|
||||
|
||||
var err common.RouteError
|
||||
|
@ -671,7 +683,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
handle, ok := RouteMap[common.Config.DefaultRoute]
|
||||
if !ok {
|
||||
// TODO: Make this a startup error not a runtime one
|
||||
log.Print("Unable to find the default route")
|
||||
router.requestLogger.Print("Unable to find the default route")
|
||||
common.NotFound(w,req,nil)
|
||||
return
|
||||
}
|
||||
|
@ -694,10 +706,11 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO: Log all bad routes for the admin to figure out where users are going wrong?
|
||||
lowerPath := strings.ToLower(req.URL.Path)
|
||||
if strings.Contains(lowerPath,"admin") || strings.Contains(lowerPath,"sql") || strings.Contains(lowerPath,"manage") || strings.Contains(lowerPath,"//") || strings.Contains(lowerPath,"\\\\") || strings.Contains(lowerPath,"wp") || strings.Contains(lowerPath,"wordpress") || strings.Contains(lowerPath,"config") || strings.Contains(lowerPath,"setup") || strings.Contains(lowerPath,"install") || strings.Contains(lowerPath,"update") || strings.Contains(lowerPath,"php") {
|
||||
router.SuspiciousRequest(req)
|
||||
router.SuspiciousRequest(req,"Bad Route")
|
||||
} else {
|
||||
router.DumpRequest(req,"Bad Route")
|
||||
}
|
||||
counters.RouteViewCounter.Bump({{.AllRouteMap.BadRoute}})
|
||||
common.NotFound(w,req,nil)
|
||||
|
|
|
@ -105,17 +105,8 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.U
|
|||
}
|
||||
|
||||
password := r.PostFormValue("password")
|
||||
switch password {
|
||||
case "":
|
||||
return common.LocalError("You didn't put in a password.", w, r, user)
|
||||
case username:
|
||||
return common.LocalError("You can't use your username as your password.", w, r, user)
|
||||
case email:
|
||||
return common.LocalError("You can't use your email as your password.", w, r, user)
|
||||
}
|
||||
|
||||
// ? Move this into Create()? What if we want to programatically set weak passwords for tests?
|
||||
err := common.WeakPassword(password)
|
||||
err := common.WeakPassword(password, username, email)
|
||||
if err != nil {
|
||||
return common.LocalError(err.Error(), w, r, user)
|
||||
}
|
||||
|
|
2
run.bat
2
run.bat
|
@ -56,5 +56,5 @@ if %errorlevel% neq 0 (
|
|||
echo Running Gosora
|
||||
gosora.exe
|
||||
rem Or you could redirect the output to a file
|
||||
rem gosora.exe > ops.log 2>&1
|
||||
rem gosora.exe > ./logs/ops.log 2>&1
|
||||
pause
|
|
@ -1,4 +1,6 @@
|
|||
{
|
||||
"DBVersion":"0",
|
||||
"DynamicFileVersion":"0"
|
||||
"DynamicFileVersion":"0",
|
||||
"MinGoVersion":"1.9",
|
||||
"MinVersion":""
|
||||
}
|
|
@ -30,3 +30,6 @@ go get -u github.com/fsnotify/fsnotify
|
|||
|
||||
echo "Updating Go Git"
|
||||
go get -u gopkg.in/src-d/go-git.v4/...
|
||||
|
||||
echo "Updating GopherJS"
|
||||
go get -u github.com/gopherjs/gopherjs
|
|
@ -89,5 +89,12 @@ if %errorlevel% neq 0 (
|
|||
exit /b %errorlevel%
|
||||
)
|
||||
|
||||
echo Updating GopherJS
|
||||
go get -u github.com/gopherjs/gopherjs
|
||||
if %errorlevel% neq 0 (
|
||||
pause
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
|
||||
echo The dependencies were successfully updated
|
||||
pause
|
||||
|
|
|
@ -92,6 +92,13 @@ if %errorlevel% neq 0 (
|
|||
exit /b %errorlevel%
|
||||
)
|
||||
|
||||
echo Updating GopherJS
|
||||
go get -u github.com/gopherjs/gopherjs
|
||||
if %errorlevel% neq 0 (
|
||||
pause
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
|
||||
|
||||
echo Building the updater
|
||||
go generate
|
||||
|
|
|
@ -4,7 +4,9 @@ import (
|
|||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"syscall"
|
||||
|
||||
"gopkg.in/src-d/go-git.v4"
|
||||
)
|
||||
|
@ -62,7 +64,17 @@ func updater(scanner *bufio.Scanner) error {
|
|||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Commit details:")
|
||||
commit, err := repo.CommitObject(headRef.Hash())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Commit details:", commit)
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
err = syscall.Exec("./patcher.bat", []string{}, os.Environ())
|
||||
default: //linux, etc.
|
||||
err = syscall.Exec("./patcher-linux", []string{}, os.Environ())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue