Add UseConvos permission.

Use UseConvos permission instead of ban flags in convo perm checks.
Stop users without the UseConvos permission from editing convo replies, although they can still delete them for privacy reasons.

Shorten some things and reduce the amount of boilerplate.
Add a few misc parser test cases.
Fix footer and tweak indentation.
This commit is contained in:
Azareal 2019-10-06 10:34:09 +10:00
parent ff48ec9d86
commit 5705252029
24 changed files with 868 additions and 1044 deletions

View File

@ -8,15 +8,14 @@ import (
"runtime/debug"
"strconv"
"github.com/Azareal/Gosora/query_gen"
qgen "github.com/Azareal/Gosora/query_gen"
)
// TODO: Make sure all the errors in this file propagate upwards properly
func main() {
// Capture panics instead of closing the window at a superhuman speed before the user can read the message on Windows
defer func() {
r := recover()
if r != nil {
if r := recover(); r != nil {
fmt.Println(r)
debug.PrintStack()
return
@ -109,6 +108,8 @@ func writeStatements(adapter qgen.Adapter) error {
return nil
}
type si = map[string]interface{}
func seedTables(adapter qgen.Adapter) error {
qgen.Install.AddIndex("topics", "parentID", "parentID")
qgen.Install.AddIndex("replies", "tid", "tid")
@ -156,6 +157,9 @@ func seedTables(adapter qgen.Adapter) error {
Non-staff Global Permissions:
UploadFiles
UploadAvatars
UseConvos
// CreateConvo ?
// CreateConvoReply ?
Forum Permissions:
ViewTopic
@ -172,11 +176,11 @@ func seedTables(adapter qgen.Adapter) error {
*/
// TODO: Set the permissions on a struct and then serialize the struct and insert that instead of writing raw JSON
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, is_admin, tag", `'Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,"Admin"`)
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, is_admin, tag", `'Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,"Admin"`)
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, tag", `'Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,"Mod"`)
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, tag", `'Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,"Mod"`)
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms", `'Member','{"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}'`)
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms", `'Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}'`)
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_banned", `'Banned','{"ViewTopic":true}','{}',1`)
@ -223,31 +227,31 @@ func seedTables(adapter qgen.Adapter) error {
qgen.Install.SimpleInsert("menus", "", "")
// Go maps have a random iteration order, so we have to do this, otherwise the schema files will become unstable and harder to audit
var order = 0
var mOrder = "mid, name, htmlID, cssClass, position, path, aria, tooltip, guestOnly, memberOnly, staffOnly, adminOnly"
var addMenuItem = func(data map[string]interface{}) {
order := 0
mOrder := "mid, name, htmlID, cssClass, position, path, aria, tooltip, guestOnly, memberOnly, staffOnly, adminOnly"
addMenuItem := func(data map[string]interface{}) {
cols, values := qgen.InterfaceMapToInsertStrings(data, mOrder)
qgen.Install.SimpleInsert("menu_items", cols+", order", values+","+strconv.Itoa(order))
order++
}
addMenuItem(map[string]interface{}{"mid": 1, "name": "{lang.menu_forums}", "htmlID": "menu_forums", "position": "left", "path": "/forums/", "aria": "{lang.menu_forums_aria}", "tooltip": "{lang.menu_forums_tooltip}"})
addMenuItem(si{"mid": 1, "name": "{lang.menu_forums}", "htmlID": "menu_forums", "position": "left", "path": "/forums/", "aria": "{lang.menu_forums_aria}", "tooltip": "{lang.menu_forums_tooltip}"})
addMenuItem(map[string]interface{}{"mid": 1, "name": "{lang.menu_topics}", "htmlID": "menu_topics", "cssClass": "menu_topics", "position": "left", "path": "/topics/", "aria": "{lang.menu_topics_aria}", "tooltip": "{lang.menu_topics_tooltip}"})
addMenuItem(si{"mid": 1, "name": "{lang.menu_topics}", "htmlID": "menu_topics", "cssClass": "menu_topics", "position": "left", "path": "/topics/", "aria": "{lang.menu_topics_aria}", "tooltip": "{lang.menu_topics_tooltip}"})
addMenuItem(map[string]interface{}{"mid": 1, "htmlID": "general_alerts", "cssClass": "menu_alerts", "position": "right", "tmplName": "menu_alerts"})
addMenuItem(si{"mid": 1, "htmlID": "general_alerts", "cssClass": "menu_alerts", "position": "right", "tmplName": "menu_alerts"})
addMenuItem(map[string]interface{}{"mid": 1, "name": "{lang.menu_account}", "cssClass": "menu_account", "position": "left", "path": "/user/edit/", "aria": "{lang.menu_account_aria}", "tooltip": "{lang.menu_account_tooltip}", "memberOnly": true})
addMenuItem(si{"mid": 1, "name": "{lang.menu_account}", "cssClass": "menu_account", "position": "left", "path": "/user/edit/", "aria": "{lang.menu_account_aria}", "tooltip": "{lang.menu_account_tooltip}", "memberOnly": true})
addMenuItem(map[string]interface{}{"mid": 1, "name": "{lang.menu_profile}", "cssClass": "menu_profile", "position": "left", "path": "{me.Link}", "aria": "{lang.menu_profile_aria}", "tooltip": "{lang.menu_profile_tooltip}", "memberOnly": true})
addMenuItem(si{"mid": 1, "name": "{lang.menu_profile}", "cssClass": "menu_profile", "position": "left", "path": "{me.Link}", "aria": "{lang.menu_profile_aria}", "tooltip": "{lang.menu_profile_tooltip}", "memberOnly": true})
addMenuItem(map[string]interface{}{"mid": 1, "name": "{lang.menu_panel}", "cssClass": "menu_panel menu_account", "position": "left", "path": "/panel/", "aria": "{lang.menu_panel_aria}", "tooltip": "{lang.menu_panel_tooltip}", "memberOnly": true, "staffOnly": true})
addMenuItem(si{"mid": 1, "name": "{lang.menu_panel}", "cssClass": "menu_panel menu_account", "position": "left", "path": "/panel/", "aria": "{lang.menu_panel_aria}", "tooltip": "{lang.menu_panel_tooltip}", "memberOnly": true, "staffOnly": true})
addMenuItem(map[string]interface{}{"mid": 1, "name": "{lang.menu_logout}", "cssClass": "menu_logout", "position": "left", "path": "/accounts/logout/?session={me.Session}", "aria": "{lang.menu_logout_aria}", "tooltip": "{lang.menu_logout_tooltip}", "memberOnly": true})
addMenuItem(si{"mid": 1, "name": "{lang.menu_logout}", "cssClass": "menu_logout", "position": "left", "path": "/accounts/logout/?s={me.Session}", "aria": "{lang.menu_logout_aria}", "tooltip": "{lang.menu_logout_tooltip}", "memberOnly": true})
addMenuItem(map[string]interface{}{"mid": 1, "name": "{lang.menu_register}", "cssClass": "menu_register", "position": "left", "path": "/accounts/create/", "aria": "{lang.menu_register_aria}", "tooltip": "{lang.menu_register_tooltip}", "guestOnly": true})
addMenuItem(si{"mid": 1, "name": "{lang.menu_register}", "cssClass": "menu_register", "position": "left", "path": "/accounts/create/", "aria": "{lang.menu_register_aria}", "tooltip": "{lang.menu_register_tooltip}", "guestOnly": true})
addMenuItem(map[string]interface{}{"mid": 1, "name": "{lang.menu_login}", "cssClass": "menu_login", "position": "left", "path": "/accounts/login/", "aria": "{lang.menu_login_aria}", "tooltip": "{lang.menu_login_tooltip}", "guestOnly": true})
addMenuItem(si{"mid": 1, "name": "{lang.menu_login}", "cssClass": "menu_login", "position": "left", "path": "/accounts/login/", "aria": "{lang.menu_login_aria}", "tooltip": "{lang.menu_login_tooltip}", "guestOnly": true})
return nil
}
@ -263,77 +267,77 @@ func seedTables(adapter qgen.Adapter) error {
type LitStr string
func writeSelects(adapter qgen.Adapter) error {
build := adapter.Builder()
func writeSelects(a qgen.Adapter) error {
b := a.Builder()
// Looking for getTopic? Your statement is in another castle
//build.Select("isPluginInstalled").Table("plugins").Columns("installed").Where("uname = ?").Parse()
//b.Select("isPluginInstalled").Table("plugins").Columns("installed").Where("uname = ?").Parse()
build.Select("forumEntryExists").Table("forums").Columns("fid").Where("name = ''").Orderby("fid ASC").Limit("0,1").Parse()
b.Select("forumEntryExists").Table("forums").Columns("fid").Where("name = ''").Orderby("fid ASC").Limit("0,1").Parse()
build.Select("groupEntryExists").Table("users_groups").Columns("gid").Where("name = ''").Orderby("gid ASC").Limit("0,1").Parse()
b.Select("groupEntryExists").Table("users_groups").Columns("gid").Where("name = ''").Orderby("gid ASC").Limit("0,1").Parse()
return nil
}
func writeLeftJoins(adapter qgen.Adapter) error {
adapter.SimpleLeftJoin("getForumTopics", "topics", "users", "topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, users.name, users.avatar", "topics.createdBy = users.uid", "topics.parentID = ?", "topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy desc", "")
func writeLeftJoins(a qgen.Adapter) error {
a.SimpleLeftJoin("getForumTopics", "topics", "users", "topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, users.name, users.avatar", "topics.createdBy = users.uid", "topics.parentID = ?", "topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy desc", "")
return nil
}
func writeInnerJoins(adapter qgen.Adapter) (err error) {
func writeInnerJoins(a qgen.Adapter) (err error) {
return nil
}
func writeInserts(adapter qgen.Adapter) error {
build := adapter.Builder()
func writeInserts(a qgen.Adapter) error {
b := a.Builder()
build.Insert("addForumPermsToForum").Table("forums_permissions").Columns("gid,fid,preset,permissions").Fields("?,?,?,?").Parse()
b.Insert("addForumPermsToForum").Table("forums_permissions").Columns("gid,fid,preset,permissions").Fields("?,?,?,?").Parse()
return nil
}
func writeUpdates(adapter qgen.Adapter) error {
build := adapter.Builder()
func writeUpdates(a qgen.Adapter) error {
b := a.Builder()
build.Update("updateEmail").Table("emails").Set("email = ?, uid = ?, validated = ?, token = ?").Where("email = ?").Parse()
b.Update("updateEmail").Table("emails").Set("email = ?, uid = ?, validated = ?, token = ?").Where("email = ?").Parse()
build.Update("setTempGroup").Table("users").Set("temp_group = ?").Where("uid = ?").Parse()
b.Update("setTempGroup").Table("users").Set("temp_group = ?").Where("uid = ?").Parse()
build.Update("bumpSync").Table("sync").Set("last_update = UTC_TIMESTAMP()").Parse()
b.Update("bumpSync").Table("sync").Set("last_update = UTC_TIMESTAMP()").Parse()
return nil
}
func writeDeletes(adapter qgen.Adapter) error {
build := adapter.Builder()
func writeDeletes(a qgen.Adapter) error {
b := a.Builder()
//build.Delete("deleteForumPermsByForum").Table("forums_permissions").Where("fid = ?").Parse()
//b.Delete("deleteForumPermsByForum").Table("forums_permissions").Where("fid = ?").Parse()
build.Delete("deleteActivityStreamMatch").Table("activity_stream_matches").Where("watcher = ? AND asid = ?").Parse()
//build.Delete("deleteActivityStreamMatchesByWatcher").Table("activity_stream_matches").Where("watcher = ?").Parse()
b.Delete("deleteActivityStreamMatch").Table("activity_stream_matches").Where("watcher = ? AND asid = ?").Parse()
//b.Delete("deleteActivityStreamMatchesByWatcher").Table("activity_stream_matches").Where("watcher = ?").Parse()
return nil
}
func writeSimpleCounts(adapter qgen.Adapter) error {
func writeSimpleCounts(a qgen.Adapter) error {
return nil
}
func writeInsertSelects(adapter qgen.Adapter) error {
/*adapter.SimpleInsertSelect("addForumPermsToForumAdmins",
func writeInsertSelects(a qgen.Adapter) error {
/*a.SimpleInsertSelect("addForumPermsToForumAdmins",
qgen.DB_Insert{"forums_permissions", "gid, fid, preset, permissions", ""},
qgen.DB_Select{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 1", "", ""},
)*/
/*adapter.SimpleInsertSelect("addForumPermsToForumStaff",
/*a.SimpleInsertSelect("addForumPermsToForumStaff",
qgen.DB_Insert{"forums_permissions", "gid, fid, preset, permissions", ""},
qgen.DB_Select{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 0 AND is_mod = 1", "", ""},
)*/
/*adapter.SimpleInsertSelect("addForumPermsToForumMembers",
/*a.SimpleInsertSelect("addForumPermsToForumMembers",
qgen.DB_Insert{"forums_permissions", "gid, fid, preset, permissions", ""},
qgen.DB_Select{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 0 AND is_mod = 0 AND is_banned = 0", "", ""},
)*/
@ -342,11 +346,11 @@ func writeInsertSelects(adapter qgen.Adapter) error {
}
// nolint
func writeInsertLeftJoins(adapter qgen.Adapter) error {
func writeInsertLeftJoins(a qgen.Adapter) error {
return nil
}
func writeInsertInnerJoins(adapter qgen.Adapter) error {
func writeInsertInnerJoins(a qgen.Adapter) error {
return nil
}

View File

@ -4,8 +4,8 @@ import (
"encoding/json"
"log"
"github.com/Azareal/Gosora/query_gen"
"github.com/Azareal/Gosora/common/phrases"
qgen "github.com/Azareal/Gosora/query_gen"
)
// TODO: Refactor the perms system
@ -39,6 +39,7 @@ var GlobalPermList = []string{
"ViewIPs",
"UploadFiles",
"UploadAvatars",
"UseConvos",
}
// Permission Structure: ActionComponent[Subcomponent]Flag
@ -67,6 +68,7 @@ type Perms struct {
// Global non-staff permissions
UploadFiles bool
UploadAvatars bool
UseConvos bool
// Forum permissions
ViewTopic bool
@ -122,6 +124,7 @@ func init() {
UploadFiles: true,
UploadAvatars: true,
UseConvos: true,
ViewTopic: true,
LikeItem: true,

View File

@ -54,14 +54,14 @@ func init() {
})
}
func (setting *Setting) Copy() (out *Setting) {
func (s *Setting) Copy() (out *Setting) {
out = &Setting{Name: ""}
*out = *setting
*out = *s
return out
}
func LoadSettings() error {
var sBox = SettingMap(make(map[string]interface{}))
sBox := SettingMap(make(map[string]interface{}))
settings, err := sBox.BypassGetAll()
if err != nil {
return err
@ -122,9 +122,9 @@ func (sBox SettingMap) ParseSetting(sname string, scontent string, stype string,
}
func (sBox SettingMap) BypassGet(name string) (*Setting, error) {
setting := &Setting{Name: name}
err := settingStmts.get.QueryRow(name).Scan(&setting.Content, &setting.Type, &setting.Constraint)
return setting, err
s := &Setting{Name: name}
err := settingStmts.get.QueryRow(name).Scan(&s.Content, &s.Type, &s.Constraint)
return s, err
}
func (sBox SettingMap) BypassGetAll() (settingList []*Setting, err error) {
@ -135,18 +135,18 @@ func (sBox SettingMap) BypassGetAll() (settingList []*Setting, err error) {
defer rows.Close()
for rows.Next() {
setting := &Setting{Name: ""}
err := rows.Scan(&setting.Name, &setting.Content, &setting.Type, &setting.Constraint)
s := &Setting{Name: ""}
err := rows.Scan(&s.Name, &s.Content, &s.Type, &s.Constraint)
if err != nil {
return nil, err
}
settingList = append(settingList, setting)
settingList = append(settingList, s)
}
return settingList, rows.Err()
}
func (sBox SettingMap) Update(name string, content string) RouteError {
setting, err := sBox.BypassGet(name)
s, err := sBox.BypassGet(name)
if err == ErrNoRows {
return FromError(err)
} else if err != nil {
@ -154,7 +154,7 @@ func (sBox SettingMap) Update(name string, content string) RouteError {
}
// TODO: Why is this here and not in a common function?
if setting.Type == "bool" {
if s.Type == "bool" {
if content == "on" || content == "1" {
content = "1"
} else {
@ -162,7 +162,7 @@ func (sBox SettingMap) Update(name string, content string) RouteError {
}
}
err = sBox.ParseSetting(name, content, setting.Type, setting.Constraint)
err = sBox.ParseSetting(name, content, s.Type, s.Constraint)
if err != nil {
return FromError(err)
}

View File

@ -374,8 +374,7 @@ func BenchmarkBadRouteGuestRouteParallelWithRouter(b *testing.B) {
func binit(b *testing.B) {
b.ReportAllocs()
err := gloinit()
if err != nil {
if err := gloinit(); err != nil {
b.Fatal(err)
}
}
@ -785,8 +784,7 @@ func BenchmarkRoutesSerial(b *testing.B) {
func BenchmarkQueryTopicParallel(b *testing.B) {
b.ReportAllocs()
err := gloinit()
if err != nil {
if err := gloinit(); err != nil {
b.Fatal(err)
}
@ -807,8 +805,7 @@ func BenchmarkQueryTopicParallel(b *testing.B) {
func BenchmarkQueryPreparedTopicParallel(b *testing.B) {
b.ReportAllocs()
err := gloinit()
if err != nil {
if err := gloinit(); err != nil {
b.Fatal(err)
}
@ -836,8 +833,7 @@ func BenchmarkQueryPreparedTopicParallel(b *testing.B) {
func BenchmarkUserGet(b *testing.B) {
b.ReportAllocs()
err := gloinit()
if err != nil {
if err := gloinit(); err != nil {
b.Fatal(err)
}
@ -855,8 +851,7 @@ func BenchmarkUserGet(b *testing.B) {
func BenchmarkUserBypassGet(b *testing.B) {
b.ReportAllocs()
err := gloinit()
if err != nil {
if err := gloinit(); err != nil {
b.Fatal(err)
}
@ -972,149 +967,62 @@ func BenchmarkParserSerial(b *testing.B) {
func BenchmarkBBCodePluginWithRegexpSerial(b *testing.B) {
b.ReportAllocs()
b.Run("empty_post", func(b *testing.B) {
f := func(name string, msg string) {
b.Run(name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeRegexParse("")
_ = bbcodeRegexParse(msg)
}
})
b.Run("short_post", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeRegexParse("Hey everyone, how's it going?")
}
})
b.Run("one_smily", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeRegexParse("Hey everyone, how's it going? :)")
}
})
b.Run("five_smilies", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeRegexParse("Hey everyone, how's it going? :):):):):)")
}
})
b.Run("ten_smilies", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeRegexParse("Hey everyone, how's it going? :):):):):):):):):):)")
}
})
b.Run("twenty_smilies", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeRegexParse("Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)")
}
})
b.Run("one_bold", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeRegexParse("[b]H[/b]ey everyone, how's it going?")
}
})
b.Run("five_bold", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeRegexParse("[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?")
}
})
b.Run("ten_bold", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeRegexParse("[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?")
}
})
f("empty_post","")
f("short_post","Hey everyone, how's it going?")
f("one_smily","Hey everyone, how's it going? :)")
f("five_smilies","Hey everyone, how's it going? :):):):):)")
f("ten_smilies","Hey everyone, how's it going? :):):):):):):):):):)")
f("twenty_smilies","Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)")
f("one_bold","[b]H[/b]ey everyone, how's it going?")
f("five_bold","[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?")
f("ten_bold","[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?")
}
func BenchmarkBBCodePluginWithoutCodeTagSerial(b *testing.B) {
b.ReportAllocs()
b.Run("empty_post", func(b *testing.B) {
f := func(name string, msg string) {
b.Run(name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeParseWithoutCode("")
_ = bbcodeParseWithoutCode(msg)
}
})
b.Run("short_post", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeParseWithoutCode("Hey everyone, how's it going?")
}
})
b.Run("one_smily", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeParseWithoutCode("Hey everyone, how's it going? :)")
}
})
b.Run("five_smilies", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeParseWithoutCode("Hey everyone, how's it going? :):):):):)")
}
})
b.Run("ten_smilies", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeParseWithoutCode("Hey everyone, how's it going? :):):):):):):):):):)")
}
})
b.Run("twenty_smilies", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeParseWithoutCode("Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)")
}
})
b.Run("one_bold", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeParseWithoutCode("[b]H[/b]ey everyone, how's it going?")
}
})
b.Run("five_bold", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeParseWithoutCode("[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?")
}
})
b.Run("ten_bold", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeParseWithoutCode("[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?")
}
})
f("empty_post","")
f("short_post","Hey everyone, how's it going?")
f("one_smily","Hey everyone, how's it going? :)")
f("five_smilies","Hey everyone, how's it going? :):):):):)")
f("ten_smilies","Hey everyone, how's it going? :):):):):):):):):):)")
f("twenty_smilies","Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)")
f("one_bold","[b]H[/b]ey everyone, how's it going?")
f("five_bold","[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?")
f("ten_bold","[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?")
}
func BenchmarkBBCodePluginWithFullParserSerial(b *testing.B) {
b.ReportAllocs()
b.Run("empty_post", func(b *testing.B) {
f := func(name string, msg string) {
b.Run(name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeFullParse("")
_ = bbcodeFullParse(msg)
}
})
b.Run("short_post", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeFullParse("Hey everyone, how's it going?")
}
})
b.Run("one_smily", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeFullParse("Hey everyone, how's it going? :)")
}
})
b.Run("five_smilies", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeFullParse("Hey everyone, how's it going? :):):):):)")
}
})
b.Run("ten_smilies", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeFullParse("Hey everyone, how's it going? :):):):):):):):):):)")
}
})
b.Run("twenty_smilies", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeFullParse("Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)")
}
})
b.Run("one_bold", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeFullParse("[b]H[/b]ey everyone, how's it going?")
}
})
b.Run("five_bold", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeFullParse("[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?")
}
})
b.Run("ten_bold", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bbcodeFullParse("[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?")
}
})
f("empty_post","")
f("short_post","Hey everyone, how's it going?")
f("one_smily","Hey everyone, how's it going? :)")
f("five_smilies","Hey everyone, how's it going? :):):):):)")
f("ten_smilies","Hey everyone, how's it going? :):):):):):):):):):)")
f("twenty_smilies","Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)")
f("one_bold","[b]H[/b]ey everyone, how's it going?")
f("five_bold","[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?")
f("ten_bold","[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?")
}
func TestLevels(t *testing.T) {
@ -1209,19 +1117,19 @@ func TestForumsAdminRoute(t *testing.T) {
if !admin.Is_Admin {
t.Fatal("UID1 is not an admin")
}
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year}
adminUidCookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
adminSessionCookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year}
forums_w := httptest.NewRecorder()
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
forums_req_admin := forums_req
forums_req_admin.AddCookie(&admin_uid_cookie)
forums_req_admin.AddCookie(&admin_session_cookie)
forums_handler := http.HandlerFunc(route_forums)
forumsW := httptest.NewRecorder()
forumsReq := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
forumsReqAdmin := forums_req
forumsReqAdmin.AddCookie(&adminUidCookie)
forumsReqAdmin.AddCookie(&adminSessionCookie)
forumsHandler := http.HandlerFunc(route_forums)
forums_handler.ServeHTTP(forums_w,forums_req_admin)
if forums_w.Code != 200 {
t.Fatal(forums_w.Body)
forumsHandler.ServeHTTP(forumsW,forumsReqAdmin)
if forumsW.Code != 200 {
t.Fatal(forumsW.Body)
}
}
@ -1316,7 +1224,7 @@ func TestForumsGuestRoute(t *testing.T) {
func TestSplittyThing(t *testing.T) {
var extraData string
var path = "/pages/hohoho"
path := "/pages/hohoho"
t.Log("Raw Path:", path)
if path[len(path)-1] != '/' {
extraData = path[strings.LastIndexByte(path, '/')+1:]

View File

@ -29,7 +29,8 @@
"ViewIPs": "Can view IP addresses",
"UploadFiles": "Can upload files",
"UploadAvatars": "Can upload avatars"
"UploadAvatars": "Can upload avatars",
"UseConvos":"Can use conversations"
},
"LocalPerms": {

55
main.go
View File

@ -25,8 +25,8 @@ import (
"time"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/counters"
"github.com/Azareal/Gosora/common/phrases"
co "github.com/Azareal/Gosora/common/counters"
p "github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen"
"github.com/Azareal/Gosora/routes"
"github.com/fsnotify/fsnotify"
@ -143,40 +143,33 @@ func storeInit() (err error) {
return errors.WithStack(err)
}
err = phrases.InitPhrases(c.Site.Language)
if err != nil {
if err = p.InitPhrases(c.Site.Language); err != nil {
return errors.WithStack(err)
}
err = c.InitEmoji()
if err != nil {
if err = c.InitEmoji(); err != nil {
return errors.WithStack(err)
}
log.Print("Loading the static files.")
err = c.Themes.LoadStaticFiles()
if err != nil {
if err = c.Themes.LoadStaticFiles(); err != nil {
return errors.WithStack(err)
}
err = c.StaticFiles.Init()
if err != nil {
if err = c.StaticFiles.Init(); err != nil {
return errors.WithStack(err)
}
err = c.StaticFiles.JSTmplInit()
if err != nil {
if err = c.StaticFiles.JSTmplInit(); err != nil {
return errors.WithStack(err)
}
log.Print("Initialising the widgets")
c.Widgets = c.NewDefaultWidgetStore()
err = c.InitWidgets()
if err != nil {
if err = c.InitWidgets(); err != nil {
return errors.WithStack(err)
}
log.Print("Initialising the menu item list")
c.Menus = c.NewDefaultMenuStore()
err = c.Menus.Load(1) // 1 = the default menu
if err != nil {
if err = c.Menus.Load(1); err != nil { // 1 = the default menu
return errors.WithStack(err)
}
menuHold, err := c.Menus.Get(1)
@ -269,47 +262,47 @@ func storeInit() (err error) {
c.Thumbnailer = c.NewCaireThumbnailer()
log.Print("Initialising the view counters")
counters.GlobalViewCounter, err = counters.NewGlobalViewCounter(acc)
co.GlobalViewCounter, err = co.NewGlobalViewCounter(acc)
if err != nil {
return errors.WithStack(err)
}
counters.AgentViewCounter, err = counters.NewDefaultAgentViewCounter(acc)
co.AgentViewCounter, err = co.NewDefaultAgentViewCounter(acc)
if err != nil {
return errors.WithStack(err)
}
counters.OSViewCounter, err = counters.NewDefaultOSViewCounter(acc)
co.OSViewCounter, err = co.NewDefaultOSViewCounter(acc)
if err != nil {
return errors.WithStack(err)
}
counters.LangViewCounter, err = counters.NewDefaultLangViewCounter(acc)
co.LangViewCounter, err = co.NewDefaultLangViewCounter(acc)
if err != nil {
return errors.WithStack(err)
}
counters.RouteViewCounter, err = counters.NewDefaultRouteViewCounter(acc)
co.RouteViewCounter, err = co.NewDefaultRouteViewCounter(acc)
if err != nil {
return errors.WithStack(err)
}
counters.PostCounter, err = counters.NewPostCounter()
co.PostCounter, err = co.NewPostCounter()
if err != nil {
return errors.WithStack(err)
}
counters.TopicCounter, err = counters.NewTopicCounter()
co.TopicCounter, err = co.NewTopicCounter()
if err != nil {
return errors.WithStack(err)
}
counters.TopicViewCounter, err = counters.NewDefaultTopicViewCounter()
co.TopicViewCounter, err = co.NewDefaultTopicViewCounter()
if err != nil {
return errors.WithStack(err)
}
counters.ForumViewCounter, err = counters.NewDefaultForumViewCounter()
co.ForumViewCounter, err = co.NewDefaultForumViewCounter()
if err != nil {
return errors.WithStack(err)
}
counters.ReferrerTracker, err = counters.NewDefaultReferrerTracker()
co.ReferrerTracker, err = co.NewDefaultReferrerTracker()
if err != nil {
return errors.WithStack(err)
}
counters.MemoryCounter, err = counters.NewMemoryCounter(acc)
co.MemoryCounter, err = co.NewMemoryCounter(acc)
if err != nil {
return errors.WithStack(err)
}
@ -422,8 +415,8 @@ func main() {
defer watcher.Close()
go func() {
var modifiedFileEvent = func(path string) error {
var pathBits = strings.Split(path, "\\")
modifiedFileEvent := func(path string) error {
pathBits := strings.Split(path, "\\")
if len(pathBits) == 0 {
return nil
}
@ -503,7 +496,7 @@ func main() {
var lastEvictedCount int
var couldNotDealloc bool
var secondTicker = time.NewTicker(time.Second)
secondTicker := time.NewTicker(time.Second)
for {
select {
case <-secondTicker.C:
@ -576,7 +569,7 @@ func main() {
func startServer() {
// We might not need the timeouts, if we're behind a reverse-proxy like Nginx
var newServer = func(addr string, handler http.Handler) *http.Server {
newServer := func(addr string, handler http.Handler) *http.Server {
rtime := c.Config.ReadTimeout
if rtime == 0 {
rtime = 8

View File

@ -15,8 +15,7 @@ import (
)
func miscinit(t *testing.T) {
err := gloinit()
if err != nil {
if err := gloinit(); err != nil {
t.Fatal(err)
}
}
@ -85,7 +84,7 @@ func userStoreTest(t *testing.T, newUserID int) {
user, err := c.Users.Get(1)
recordMustExist(t, err, "Couldn't find UID #1")
var expectW = func(cond bool, expec bool, prefix string, suffix string) {
expectW := func(cond bool, expec bool, prefix string, suffix string) {
midfix := "should not be"
if expec {
midfix = "should be"
@ -94,15 +93,15 @@ func userStoreTest(t *testing.T, newUserID int) {
}
// TODO: Add email checks too? Do them separately?
var expectUser = func(user *c.User, uid int, name string, group int, super bool, admin bool, mod bool, banned bool) {
expect(t, user.ID == uid, fmt.Sprintf("user.ID should be %d. Got '%d' instead.", uid, user.ID))
expect(t, user.Name == name, fmt.Sprintf("user.Name should be '%s', not '%s'", name, user.Name))
expectW(user.Group == group, true, user.Name, "in group"+strconv.Itoa(group))
expectW(user.IsSuperAdmin == super, super, user.Name, "a super admin")
expectW(user.IsAdmin == admin, admin, user.Name, "an admin")
expectW(user.IsSuperMod == mod, mod, user.Name, "a super mod")
expectW(user.IsMod == mod, mod, user.Name, "a mod")
expectW(user.IsBanned == banned, banned, user.Name, "banned")
expectUser := func(u *c.User, uid int, name string, group int, super bool, admin bool, mod bool, banned bool) {
expect(t, u.ID == uid, fmt.Sprintf("u.ID should be %d. Got '%d' instead.", uid, u.ID))
expect(t, u.Name == name, fmt.Sprintf("u.Name should be '%s', not '%s'", name, u.Name))
expectW(u.Group == group, true, u.Name, "in group"+strconv.Itoa(group))
expectW(u.IsSuperAdmin == super, super, u.Name, "a super admin")
expectW(u.IsAdmin == admin, admin, u.Name, "an admin")
expectW(u.IsSuperMod == mod, mod, u.Name, "a super mod")
expectW(u.IsMod == mod, mod, u.Name, "a mod")
expectW(u.IsBanned == banned, banned, u.Name, "banned")
}
expectUser(user, 1, "Admin", 1, true, true, true, false)
@ -111,7 +110,6 @@ func userStoreTest(t *testing.T, newUserID int) {
if ucache != nil {
expectIntToBeX(t, ucache.Length(), 1, "User cache length should be 1, not %d")
_, err = ucache.Get(-1)
recordMustNotExist(t, err, "UID #-1 shouldn't exist, even in the cache")
_, err = ucache.Get(0)
@ -167,7 +165,7 @@ func userStoreTest(t *testing.T, newUserID int) {
expect(t, isCacheLengthZero(ucache), fmt.Sprintf("User cache length should be 0, not %d", cacheLength(ucache)))
expectIntToBeX(t, c.Users.Count(), 1, "The number of users should be one, not %d")
var awaitingActivation = 5
awaitingActivation := 5
// TODO: Write tests for the registration validators
uid, err := c.Users.Create("Sam", "ReallyBadPassword", "sam@localhost.loc", awaitingActivation, false)
expectNilErr(t, err)
@ -215,7 +213,7 @@ func userStoreTest(t *testing.T, newUserID int) {
expectIntToBeX(t, user.Group, 5, "Sam should still be in group 5 in this copy")
// ? - What if we change the caching mechanism so it isn't hard purged and reloaded? We'll deal with that when we come to it, but for now, this is a sign of a cache bug
var afterUserFlush = func(uid int) {
afterUserFlush := func(uid int) {
if ucache != nil {
expectIntToBeX(t, ucache.Length(), 0, "User cache length should be 0, not %d")
_, err = ucache.Get(uid)
@ -252,15 +250,15 @@ func userStoreTest(t *testing.T, newUserID int) {
recordMustExist(t, err, "Couldn't find UID #%d", newUserID)
expectUser(user, newUserID, "Sam", c.Config.DefaultGroup, false, false, false, false)
var reportsForumID = 1 // TODO: Use the constant in common?
var generalForumID = 2
reportsForumID := 1 // TODO: Use the constant in common?
generalForumID := 2
dummyResponseRecorder := httptest.NewRecorder()
bytesBuffer := bytes.NewBuffer([]byte(""))
dummyRequest1 := httptest.NewRequest("", "/forum/"+strconv.Itoa(reportsForumID), bytesBuffer)
dummyRequest2 := httptest.NewRequest("", "/forum/"+strconv.Itoa(generalForumID), bytesBuffer)
var user2 *c.User
var changeGroupTest = func(oldGroup int, newGroup int) {
changeGroupTest := func(oldGroup int, newGroup int) {
err = user.ChangeGroup(newGroup)
expectNilErr(t, err)
// ! I don't think ChangeGroup should be changing the value of user... Investigate this.
@ -272,7 +270,7 @@ func userStoreTest(t *testing.T, newUserID int) {
*user2 = *user
}
var changeGroupTest2 = func(rank string, firstShouldBe bool, secondShouldBe bool) {
changeGroupTest2 := func(rank string, firstShouldBe bool, secondShouldBe bool) {
head, err := c.UserCheck(dummyResponseRecorder, dummyRequest1, user)
if err != nil {
t.Fatal(err)
@ -490,7 +488,7 @@ func topicStoreTest(t *testing.T, newID int) {
count = c.Topics.Count()
expect(t, count == 2, fmt.Sprintf("Global count for topics should be 2, not %d", count))
var iFrag = func(cond bool) string {
iFrag := func(cond bool) string {
if !cond {
return "n't"
}
@ -513,7 +511,7 @@ func topicStoreTest(t *testing.T, newID int) {
}
tcache := c.Topics.GetCache()
var shouldNotBeIn = func(tid int) {
shouldNotBeIn := func(tid int) {
if tcache != nil {
_, err = tcache.Get(tid)
recordMustNotExist(t, err, "Topic cache should be empty")
@ -581,7 +579,7 @@ func TestForumStore(t *testing.T) {
// TODO: Check the preset and forum permissions
expect(t, forum.Name == "Reports", fmt.Sprintf("FID #0 is named '%s' and not 'Reports'", forum.Name))
expect(t, !forum.Active, fmt.Sprintf("The reports forum shouldn't be active"))
var expectDesc = "All the reports go here"
expectDesc := "All the reports go here"
expect(t, forum.Desc == expectDesc, fmt.Sprintf("The forum description should be '%s' not '%s'", expectDesc, forum.Desc))
forum, err = c.Forums.BypassGet(1)
recordMustExist(t, err, "Couldn't find FID #1")
@ -732,48 +730,24 @@ func TestForumPermsStore(t *testing.T) {
c.InitPlugins()
}
var initialState = func() {
fid := 1
gid := 1
fperms, err := c.FPStore.Get(fid,gid)
f := func(fid int, gid int, msg string, inv ...bool) {
fp, err := c.FPStore.Get(fid,gid)
expectNilErr(t,err)
expect(t,fperms.ViewTopic,"admins should be able to see reports")
vt := fp.ViewTopic
if len(inv) > 0 && inv[0] == true {
vt = !vt
}
expect(t,vt,msg)
}
fid = 1
gid = 2
fperms, err = c.FPStore.Get(fid,gid)
expectNilErr(t,err)
expect(t,fperms.ViewTopic,"mods should be able to see reports")
fid = 1
gid = 3
fperms, err = c.FPStore.Get(fid,gid)
expectNilErr(t,err)
expect(t,!fperms.ViewTopic,"members should not be able to see reports")
fid = 1
gid = 4
fperms, err = c.FPStore.Get(fid,gid)
expectNilErr(t,err)
expect(t,!fperms.ViewTopic,"banned users should not be able to see reports")
fid = 2
gid = 1
fperms, err = c.FPStore.Get(fid,gid)
expectNilErr(t,err)
expect(t,fperms.ViewTopic,"admins should be able to see general")
fid = 2
gid = 3
fperms, err = c.FPStore.Get(fid,gid)
expectNilErr(t,err)
expect(t,fperms.ViewTopic,"members should be able to see general")
fid = 2
gid = 6
fperms, err = c.FPStore.Get(fid,gid)
expectNilErr(t,err)
expect(t,fperms.ViewTopic,"guests should be able to see general")
initialState := func() {
f(1,1,"admins should be able to see reports")
f(1,2,"mods should be able to see reports")
f(1,3,"members should not be able to see reports",true)
f(1,4,"banned users should not be able to see reports",true)
f(2,1,"admins should be able to see general")
f(2,3,"members should be able to see general")
f(2,6,"guests should be able to see general")
}
initialState()
@ -811,9 +785,9 @@ func TestGroupStore(t *testing.T) {
expect(t, c.Groups.Exists(0), "GID #0 should exist")
expect(t, c.Groups.Exists(1), "GID #1 should exist")
var isAdmin = true
var isMod = true
var isBanned = false
isAdmin := true
isMod := true
isBanned := false
gid, err := c.Groups.Create("Testing", "Test", isAdmin, isMod, isBanned)
expectNilErr(t, err)
expect(t, c.Groups.Exists(gid), "The group we just made doesn't exist")
@ -1032,7 +1006,7 @@ func TestProfileReplyStore(t *testing.T) {
//err = profileReply.Delete()
//expect(t,err != nil,"You shouldn't be able to delete profile replies which don't exist")
var profileID = 1
profileID := 1
prid, err := c.Prstore.Create(profileID, "Haha", 1, "::1")
expectNilErr(t, err)
expect(t, prid == 1, "The first profile reply should have an ID of 1")
@ -1265,10 +1239,14 @@ func TestPluginManager(t *testing.T) {
}
func TestPhrases(t *testing.T) {
expect(t, phrases.GetGlobalPermPhrase("BanUsers") == "Can ban users", "Not the expected phrase")
expect(t, phrases.GetGlobalPermPhrase("NoSuchPerm") == "{lang.perms[NoSuchPerm]}", "Not the expected phrase")
expect(t, phrases.GetLocalPermPhrase("ViewTopic") == "Can view topics", "Not the expected phrase")
expect(t, phrases.GetLocalPermPhrase("NoSuchPerm") == "{lang.perms[NoSuchPerm]}", "Not the expected phrase")
getPhrase := phrases.GetGlobalPermPhrase
tp := func(name string, expects string) {
expect(t, getPhrase(name) == expects, "Not the expected phrase")
}
tp("BanUsers","Can ban users")
tp("NoSuchPerm","{lang.perms[NoSuchPerm]}")
tp("ViewTopic","Can view topics")
tp("NoSuchPerm","{lang.perms[NoSuchPerm]}")
// TODO: Cover the other phrase types, also try switching between languages to see if anything strange happens
}
@ -1326,34 +1304,33 @@ func TestWordFilters(t *testing.T) {
// TODO: Expand upon the valid characters which can go in URLs?
func TestSlugs(t *testing.T) {
var res string
var msgList = &MEPairList{nil}
l := &MEPairList{nil}
c.Config.BuildSlugs = true // Flip this switch, otherwise all the tests will fail
msgList.Add("Unknown", "unknown")
msgList.Add("Unknown2", "unknown2")
msgList.Add("Unknown ", "unknown")
msgList.Add("Unknown 2", "unknown-2")
msgList.Add("Unknown 2", "unknown-2")
msgList.Add("Admin Alice", "admin-alice")
msgList.Add("Admin_Alice", "adminalice")
msgList.Add("Admin_Alice-", "adminalice")
msgList.Add("-Admin_Alice-", "adminalice")
msgList.Add("-Admin@Alice-", "adminalice")
msgList.Add("-Admin😀Alice-", "adminalice")
msgList.Add("u", "u")
msgList.Add("", "untitled")
msgList.Add(" ", "untitled")
msgList.Add("-", "untitled")
msgList.Add("--", "untitled")
msgList.Add("é", "é")
msgList.Add("-é-", "é")
msgList.Add("-你好-", "untitled")
msgList.Add("-こにちは-", "untitled")
l.Add("Unknown", "unknown")
l.Add("Unknown2", "unknown2")
l.Add("Unknown ", "unknown")
l.Add("Unknown 2", "unknown-2")
l.Add("Unknown 2", "unknown-2")
l.Add("Admin Alice", "admin-alice")
l.Add("Admin_Alice", "adminalice")
l.Add("Admin_Alice-", "adminalice")
l.Add("-Admin_Alice-", "adminalice")
l.Add("-Admin@Alice-", "adminalice")
l.Add("-Admin😀Alice-", "adminalice")
l.Add("u", "u")
l.Add("", "untitled")
l.Add(" ", "untitled")
l.Add("-", "untitled")
l.Add("--", "untitled")
l.Add("é", "é")
l.Add("-é-", "é")
l.Add("-你好-", "untitled")
l.Add("-こにちは-", "untitled")
for _, item := range msgList.Items {
for _, item := range l.Items {
t.Log("Testing string '" + item.Msg + "'")
res = c.NameToSlug(item.Msg)
res := c.NameToSlug(item.Msg)
if res != item.Expects {
t.Error("Bad output:", "'"+res+"'")
t.Error("Expected:", item.Expects)
@ -1523,14 +1500,14 @@ type METriList struct {
Items []METri
}
func (tlist *METriList) Add(args ...string) {
func (l *METriList) Add(args ...string) {
if len(args) < 2 {
panic("need 2 or more args")
}
if len(args) > 2 {
tlist.Items = append(tlist.Items, METri{args[0], args[1], args[2]})
l.Items = append(l.Items, METri{args[0], args[1], args[2]})
} else {
tlist.Items = append(tlist.Items, METri{"", args[0], args[1]})
l.Items = append(l.Items, METri{"", args[0], args[1]})
}
}
@ -1544,37 +1521,36 @@ type CountTestList struct {
Items []CountTest
}
func (tlist *CountTestList) Add(name string, msg string, expects int) {
tlist.Items = append(tlist.Items, CountTest{name, msg, expects})
func (l *CountTestList) Add(name string, msg string, expects int) {
l.Items = append(l.Items, CountTest{name, msg, expects})
}
func TestWordCount(t *testing.T) {
var msgList = &CountTestList{nil}
l := &CountTestList{nil}
l.Add("blank", "", 0)
l.Add("single-letter", "h", 1)
l.Add("single-kana", "お", 1)
l.Add("single-letter-words", "h h", 2)
l.Add("two-letter", "h", 1)
l.Add("two-kana", "おは", 1)
l.Add("two-letter-words", "hh hh", 2)
l.Add("", "h,h", 2)
l.Add("", "h,,h", 2)
l.Add("", "h, h", 2)
l.Add("", " h, h", 2)
l.Add("", "h, h ", 2)
l.Add("", " h, h ", 2)
l.Add("", "h, h", 2)
l.Add("", "h\nh", 2)
l.Add("", "h\"h", 2)
l.Add("", "h[r]h", 3)
l.Add("", "お,お", 2)
l.Add("", "お、お", 2)
l.Add("", "お\nお", 2)
l.Add("", "お”お", 2)
l.Add("", "お「あ」お", 3)
msgList.Add("blank", "", 0)
msgList.Add("single-letter", "h", 1)
msgList.Add("single-kana", "お", 1)
msgList.Add("single-letter-words", "h h", 2)
msgList.Add("two-letter", "h", 1)
msgList.Add("two-kana", "おは", 1)
msgList.Add("two-letter-words", "hh hh", 2)
msgList.Add("", "h,h", 2)
msgList.Add("", "h,,h", 2)
msgList.Add("", "h, h", 2)
msgList.Add("", " h, h", 2)
msgList.Add("", "h, h ", 2)
msgList.Add("", " h, h ", 2)
msgList.Add("", "h, h", 2)
msgList.Add("", "h\nh", 2)
msgList.Add("", "h\"h", 2)
msgList.Add("", "h[r]h", 3)
msgList.Add("", "お,お", 2)
msgList.Add("", "お、お", 2)
msgList.Add("", "お\nお", 2)
msgList.Add("", "お”お", 2)
msgList.Add("", "お「あ」お", 3)
for _, item := range msgList.Items {
for _, item := range l.Items {
res := c.WordCount(item.Msg)
if res != item.Expects {
if item.Name != "" {

View File

@ -13,114 +13,115 @@ func TestPreparser(t *testing.T) {
if !c.PluginsInited {
c.InitPlugins()
}
var msgList = &METriList{nil}
l := &METriList{nil}
// Note: The open tag is evaluated without knowledge of the close tag for efficiency and simplicity, so the parser autofills the associated close tag when it finds an open tag without a partner
msgList.Add("", "")
msgList.Add(" ", "")
msgList.Add(" hi", "hi")
msgList.Add("hi ", "hi")
msgList.Add("hi", "hi")
msgList.Add(":grinning:", "😀")
msgList.Add("😀", "😀")
msgList.Add("&nbsp;", "")
msgList.Add("<p>", "")
msgList.Add("</p>", "")
msgList.Add("<p></p>", "")
l.Add("", "")
l.Add(" ", "")
l.Add(" hi", "hi")
l.Add("hi ", "hi")
l.Add("hi", "hi")
l.Add(":grinning:", "😀")
l.Add("😀", "😀")
l.Add("&nbsp;", "")
l.Add("<p>", "")
l.Add("</p>", "")
l.Add("<p></p>", "")
msgList.Add("<", "&lt;")
msgList.Add(">", "&gt;")
msgList.Add("<meow>", "&lt;meow&gt;")
msgList.Add("&lt;", "&amp;lt;")
msgList.Add("&", "&amp;")
l.Add("<", "&lt;")
l.Add(">", "&gt;")
l.Add("<meow>", "&lt;meow&gt;")
l.Add("&lt;", "&amp;lt;")
l.Add("&", "&amp;")
// Note: strings.TrimSpace strips newlines, if there's nothing before or after them
msgList.Add("<br>", "")
msgList.Add("<br />", "")
msgList.Add("\\n", "\n", "")
msgList.Add("\\n\\n", "\n\n", "")
msgList.Add("\\n\\n\\n", "\n\n\n", "")
msgList.Add("\\r\\n", "\r\n", "") // Windows style line ending
msgList.Add("\\n\\r", "\n\r", "")
l.Add("<br>", "")
l.Add("<br />", "")
l.Add("\\n", "\n", "")
l.Add("\\n\\n", "\n\n", "")
l.Add("\\n\\n\\n", "\n\n\n", "")
l.Add("\\r\\n", "\r\n", "") // Windows style line ending
l.Add("\\n\\r", "\n\r", "")
msgList.Add("ho<br>ho", "ho\n\nho")
msgList.Add("ho<br />ho", "ho\n\nho")
msgList.Add("ho\\nho", "ho\nho", "ho\nho")
msgList.Add("ho\\n\\nho", "ho\n\nho", "ho\n\nho")
//msgList.Add("ho\\n\\n\\n\\nho", "ho\n\n\n\nho", "ho\n\n\nho")
msgList.Add("ho\\r\\nho", "ho\r\nho", "ho\nho") // Windows style line ending
msgList.Add("ho\\n\\rho", "ho\n\rho", "ho\nho")
l.Add("ho<br>ho", "ho\n\nho")
l.Add("ho<br />ho", "ho\n\nho")
l.Add("ho\\nho", "ho\nho", "ho\nho")
l.Add("ho\\n\\nho", "ho\n\nho", "ho\n\nho")
//l.Add("ho\\n\\n\\n\\nho", "ho\n\n\n\nho", "ho\n\n\nho")
l.Add("ho\\r\\nho", "ho\r\nho", "ho\nho") // Windows style line ending
l.Add("ho\\n\\rho", "ho\n\rho", "ho\nho")
msgList.Add("<b></b>", "<strong></strong>")
msgList.Add("<b>hi</b>", "<strong>hi</strong>")
msgList.Add("<b>h</b>", "<strong>h</strong>")
msgList.Add("<s>hi</s>", "<del>hi</del>")
msgList.Add("<del>hi</del>", "<del>hi</del>")
msgList.Add("<u>hi</u>", "<u>hi</u>")
msgList.Add("<em>hi</em>", "<em>hi</em>")
msgList.Add("<i>hi</i>", "<em>hi</em>")
msgList.Add("<strong>hi</strong>", "<strong>hi</strong>")
msgList.Add("<b><i>hi</i></b>", "<strong><em>hi</em></strong>")
msgList.Add("<strong><em>hi</em></strong>", "<strong><em>hi</em></strong>")
msgList.Add("<b><i><b>hi</b></i></b>", "<strong><em><strong>hi</strong></em></strong>")
msgList.Add("<strong><em><strong>hi</strong></em></strong>", "<strong><em><strong>hi</strong></em></strong>")
msgList.Add("<div>hi</div>", "&lt;div&gt;hi&lt;/div&gt;")
msgList.Add("<span>hi</span>", "hi") // This is stripped since the editor (Trumbowyg) likes blasting useless spans
msgList.Add("<span >hi</span>", "hi")
msgList.Add("<span style='background-color: yellow;'>hi</span>", "hi")
msgList.Add("<span style='background-color: yellow;'>>hi</span>", "&gt;hi")
msgList.Add("<b>hi", "<strong>hi</strong>")
msgList.Add("hi</b>", "hi&lt;/b&gt;")
msgList.Add("</b>", "&lt;/b&gt;")
msgList.Add("</del>", "&lt;/del&gt;")
msgList.Add("</strong>", "&lt;/strong&gt;")
msgList.Add("<b>", "<strong></strong>")
msgList.Add("<span style='background-color: yellow;'>hi", "hi")
msgList.Add("hi</span>", "hi")
msgList.Add("</span>", "")
msgList.Add("<span></span>", "")
msgList.Add("<span ></span>", "")
msgList.Add("<span><span></span></span>", "")
msgList.Add("<span><b></b></span>", "<strong></strong>")
msgList.Add("<h1>t</h1>", "<h2>t</h2>")
msgList.Add("<h2>t</h2>", "<h3>t</h3>")
msgList.Add("<h3>t</h3>", "<h4>t</h4>")
msgList.Add("<></>", "&lt;&gt;&lt;/&gt;")
msgList.Add("</><>", "&lt;/&gt;&lt;&gt;")
msgList.Add("<>", "&lt;&gt;")
msgList.Add("</>", "&lt;/&gt;")
msgList.Add("<p>hi</p>", "hi")
msgList.Add("<p></p>", "")
msgList.Add("<blockquote>hi</blockquote>", "<blockquote>hi</blockquote>")
msgList.Add("<blockquote><b>hi</b></blockquote>", "<blockquote><strong>hi</strong></blockquote>")
msgList.Add("<blockquote><meow>hi</meow></blockquote>", "<blockquote>&lt;meow&gt;hi&lt;/meow&gt;</blockquote>")
msgList.Add("\\<blockquote>hi</blockquote>", "&lt;blockquote&gt;hi&lt;/blockquote&gt;")
//msgList.Add("\\\\<blockquote><meow>hi</meow></blockquote>", "\\<blockquote>&lt;meow&gt;hi&lt;/meow&gt;</blockquote>") // TODO: Double escapes should print a literal backslash
//msgList.Add("&lt;blockquote&gt;hi&lt;/blockquote&gt;", "&lt;blockquote&gt;hi&lt;/blockquote&gt;") // TODO: Stop double-entitising this
msgList.Add("\\<blockquote>hi</blockquote>\\<blockquote>hi</blockquote>", "&lt;blockquote&gt;hi&lt;/blockquote&gt;&lt;blockquote&gt;hi&lt;/blockquote&gt;")
msgList.Add("\\<a itemprop=\"author\">Admin</a>", "&lt;a itemprop=&#34;author&#34;&gt;Admin&lt;/a&gt;")
msgList.Add("<blockquote>\\<a itemprop=\"author\">Admin</a></blockquote>", "<blockquote>&lt;a itemprop=&#34;author&#34;&gt;Admin&lt;/a&gt;</blockquote>")
msgList.Add("\n<blockquote>\\<a itemprop=\"author\">Admin</a></blockquote>\n", "<blockquote>&lt;a itemprop=&#34;author&#34;&gt;Admin&lt;/a&gt;</blockquote>")
msgList.Add("tt\n<blockquote>\\<a itemprop=\"author\">Admin</a></blockquote>\ntt", "tt\n<blockquote>&lt;a itemprop=&#34;author&#34;&gt;Admin&lt;/a&gt;</blockquote>\ntt")
msgList.Add("@", "@")
msgList.Add("@Admin", "@1")
msgList.Add("@Bah", "@Bah")
msgList.Add(" @Admin", "@1")
msgList.Add("\n@Admin", "@1")
msgList.Add("@Admin\n", "@1")
msgList.Add("@Admin\ndd", "@1\ndd")
msgList.Add("d@Admin", "d@Admin")
msgList.Add("\\@Admin", "@Admin")
msgList.Add("@元気", "@元気")
l.Add("<b></b>", "<strong></strong>")
l.Add("<b>hi</b>", "<strong>hi</strong>")
l.Add("<b>h</b>", "<strong>h</strong>")
l.Add("<s>hi</s>", "<del>hi</del>")
l.Add("<del>hi</del>", "<del>hi</del>")
l.Add("<u>hi</u>", "<u>hi</u>")
l.Add("<em>hi</em>", "<em>hi</em>")
l.Add("<i>hi</i>", "<em>hi</em>")
l.Add("<strong>hi</strong>", "<strong>hi</strong>")
l.Add("<b><i>hi</i></b>", "<strong><em>hi</em></strong>")
l.Add("<strong><em>hi</em></strong>", "<strong><em>hi</em></strong>")
l.Add("<b><i><b>hi</b></i></b>", "<strong><em><strong>hi</strong></em></strong>")
l.Add("<strong><em><strong>hi</strong></em></strong>", "<strong><em><strong>hi</strong></em></strong>")
l.Add("<div>hi</div>", "&lt;div&gt;hi&lt;/div&gt;")
l.Add("<span>hi</span>", "hi") // This is stripped since the editor (Trumbowyg) likes blasting useless spans
l.Add("<span >hi</span>", "hi")
l.Add("<span style='background-color: yellow;'>hi</span>", "hi")
l.Add("<span style='background-color: yellow;'>>hi</span>", "&gt;hi")
l.Add("<b>hi", "<strong>hi</strong>")
l.Add("hi</b>", "hi&lt;/b&gt;")
l.Add("</b>", "&lt;/b&gt;")
l.Add("</del>", "&lt;/del&gt;")
l.Add("</strong>", "&lt;/strong&gt;")
l.Add("<b>", "<strong></strong>")
l.Add("<span style='background-color: yellow;'>hi", "hi")
l.Add("<span style='background-color:yellow;'>hi", "hi")
l.Add("hi</span>", "hi")
l.Add("</span>", "")
l.Add("<span></span>", "")
l.Add("<span ></span>", "")
l.Add("<span><span></span></span>", "")
l.Add("<span><b></b></span>", "<strong></strong>")
l.Add("<h1>t</h1>", "<h2>t</h2>")
l.Add("<h2>t</h2>", "<h3>t</h3>")
l.Add("<h3>t</h3>", "<h4>t</h4>")
l.Add("<></>", "&lt;&gt;&lt;/&gt;")
l.Add("</><>", "&lt;/&gt;&lt;&gt;")
l.Add("<>", "&lt;&gt;")
l.Add("</>", "&lt;/&gt;")
l.Add("<p>hi</p>", "hi")
l.Add("<p></p>", "")
l.Add("<blockquote>hi</blockquote>", "<blockquote>hi</blockquote>")
l.Add("<blockquote><b>hi</b></blockquote>", "<blockquote><strong>hi</strong></blockquote>")
l.Add("<blockquote><meow>hi</meow></blockquote>", "<blockquote>&lt;meow&gt;hi&lt;/meow&gt;</blockquote>")
l.Add("\\<blockquote>hi</blockquote>", "&lt;blockquote&gt;hi&lt;/blockquote&gt;")
//l.Add("\\\\<blockquote><meow>hi</meow></blockquote>", "\\<blockquote>&lt;meow&gt;hi&lt;/meow&gt;</blockquote>") // TODO: Double escapes should print a literal backslash
//l.Add("&lt;blockquote&gt;hi&lt;/blockquote&gt;", "&lt;blockquote&gt;hi&lt;/blockquote&gt;") // TODO: Stop double-entitising this
l.Add("\\<blockquote>hi</blockquote>\\<blockquote>hi</blockquote>", "&lt;blockquote&gt;hi&lt;/blockquote&gt;&lt;blockquote&gt;hi&lt;/blockquote&gt;")
l.Add("\\<a itemprop=\"author\">Admin</a>", "&lt;a itemprop=&#34;author&#34;&gt;Admin&lt;/a&gt;")
l.Add("<blockquote>\\<a itemprop=\"author\">Admin</a></blockquote>", "<blockquote>&lt;a itemprop=&#34;author&#34;&gt;Admin&lt;/a&gt;</blockquote>")
l.Add("\n<blockquote>\\<a itemprop=\"author\">Admin</a></blockquote>\n", "<blockquote>&lt;a itemprop=&#34;author&#34;&gt;Admin&lt;/a&gt;</blockquote>")
l.Add("tt\n<blockquote>\\<a itemprop=\"author\">Admin</a></blockquote>\ntt", "tt\n<blockquote>&lt;a itemprop=&#34;author&#34;&gt;Admin&lt;/a&gt;</blockquote>\ntt")
l.Add("@", "@")
l.Add("@Admin", "@1")
l.Add("@Bah", "@Bah")
l.Add(" @Admin", "@1")
l.Add("\n@Admin", "@1")
l.Add("@Admin\n", "@1")
l.Add("@Admin\ndd", "@1\ndd")
l.Add("d@Admin", "d@Admin")
l.Add("\\@Admin", "@Admin")
l.Add("@元気", "@元気")
// TODO: More tests for unicode names?
//msgList.Add("\\\\@Admin", "@1")
//msgList.Add("byte 0", string([]byte{0}), "")
msgList.Add("byte 'a'", string([]byte{'a'}), "a")
//msgList.Add("byte 255", string([]byte{255}), "")
//msgList.Add("rune 0", string([]rune{0}), "")
//l.Add("\\\\@Admin", "@1")
//l.Add("byte 0", string([]byte{0}), "")
l.Add("byte 'a'", string([]byte{'a'}), "a")
//l.Add("byte 255", string([]byte{255}), "")
//l.Add("rune 0", string([]rune{0}), "")
// TODO: Do a test with invalid UTF-8 input
for _, item := range msgList.Items {
for _, item := range l.Items {
res := c.PreparseMessage(item.Msg)
if res != item.Expects {
if item.Name != "" {
@ -139,145 +140,148 @@ func TestParser(t *testing.T) {
if !c.PluginsInited {
c.InitPlugins()
}
var msgList = &METriList{nil}
l := &METriList{nil}
url := "github.com/Azareal/Gosora"
msgList.Add("", "")
msgList.Add("haha", "haha")
msgList.Add("<b>t</b>", "<b>t</b>")
msgList.Add("//", "//")
msgList.Add("http://", "<red>[Invalid URL]</red>")
msgList.Add("https://", "<red>[Invalid URL]</red>")
msgList.Add("ftp://", "<red>[Invalid URL]</red>")
msgList.Add("git://", "<red>[Invalid URL]</red>")
msgList.Add("ssh://", "ssh://")
l.Add("", "")
l.Add("haha", "haha")
l.Add("<b>t</b>", "<b>t</b>")
l.Add("//", "//")
l.Add("http://", "<red>[Invalid URL]</red>")
l.Add("https://", "<red>[Invalid URL]</red>")
l.Add("ftp://", "<red>[Invalid URL]</red>")
l.Add("git://", "<red>[Invalid URL]</red>")
l.Add("ssh://", "ssh://")
msgList.Add("// ", "// ")
msgList.Add("// //", "// //")
msgList.Add("// // //", "// // //")
msgList.Add("http:// ", "<red>[Invalid URL]</red> ")
msgList.Add("https:// ", "<red>[Invalid URL]</red> ")
msgList.Add("ftp:// ", "<red>[Invalid URL]</red> ")
msgList.Add("git:// ", "<red>[Invalid URL]</red> ")
msgList.Add("ssh:// ", "ssh:// ")
l.Add("// ", "// ")
l.Add("// //", "// //")
l.Add("// // //", "// // //")
l.Add("http:// ", "<red>[Invalid URL]</red> ")
l.Add("https:// ", "<red>[Invalid URL]</red> ")
l.Add("ftp:// ", "<red>[Invalid URL]</red> ")
l.Add("git:// ", "<red>[Invalid URL]</red> ")
l.Add("ssh:// ", "ssh:// ")
msgList.Add("// t", "// t")
msgList.Add("http:// t", "<red>[Invalid URL]</red> t")
l.Add("// t", "// t")
l.Add("http:// t", "<red>[Invalid URL]</red> t")
msgList.Add("http:", "http:")
msgList.Add("https:", "https:")
msgList.Add("ftp:", "ftp:")
msgList.Add("git:", "git:")
msgList.Add("ssh:", "ssh:")
l.Add("http:", "http:")
l.Add("https:", "https:")
l.Add("ftp:", "ftp:")
l.Add("git:", "git:")
l.Add("ssh:", "ssh:")
msgList.Add("http", "http")
msgList.Add("https", "https")
msgList.Add("ftp", "ftp")
msgList.Add("git", "git")
msgList.Add("ssh", "ssh")
l.Add("http", "http")
l.Add("https", "https")
l.Add("ftp", "ftp")
l.Add("git", "git")
l.Add("ssh", "ssh")
msgList.Add("ht", "ht")
msgList.Add("htt", "htt")
msgList.Add("ft", "ft")
msgList.Add("gi", "gi")
msgList.Add("ss", "ss")
msgList.Add("haha\nhaha\nhaha", "haha<br>haha<br>haha")
msgList.Add("//"+url, "<a href='//"+url+"'>//"+url+"</a>")
msgList.Add("//a", "<a href='//a'>//a</a>")
msgList.Add(" //a", " <a href='//a'>//a</a>")
msgList.Add("//a ", "<a href='//a'>//a</a> ")
msgList.Add(" //a ", " <a href='//a'>//a</a> ")
msgList.Add("d //a ", "d <a href='//a'>//a</a> ")
msgList.Add("ddd ddd //a ", "ddd ddd <a href='//a'>//a</a> ")
msgList.Add("https://"+url, "<a href='https://"+url+"'>https://"+url+"</a>")
msgList.Add("https://t", "<a href='https://t'>https://t</a>")
msgList.Add("http://"+url, "<a href='http://"+url+"'>http://"+url+"</a>")
msgList.Add("#http://"+url, "#http://"+url)
msgList.Add("@http://"+url, "<red>[Invalid Profile]</red>ttp://"+url)
msgList.Add("//"+url+"\n", "<a href='//"+url+"'>//"+url+"</a><br>")
msgList.Add("\n//"+url, "<br><a href='//"+url+"'>//"+url+"</a>")
msgList.Add("\n//"+url+"\n", "<br><a href='//"+url+"'>//"+url+"</a><br>")
msgList.Add("\n//"+url+"\n\n", "<br><a href='//"+url+"'>//"+url+"</a><br><br>")
msgList.Add("//"+url+"\n//"+url, "<a href='//"+url+"'>//"+url+"</a><br><a href='//"+url+"'>//"+url+"</a>")
msgList.Add("//"+url+"\n\n//"+url, "<a href='//"+url+"'>//"+url+"</a><br><br><a href='//"+url+"'>//"+url+"</a>")
msgList.Add("//"+c.Site.URL, "<a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a>")
msgList.Add("//"+c.Site.URL+"\n", "<a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a><br>")
msgList.Add("//"+c.Site.URL+"\n//"+c.Site.URL, "<a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a><br><a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a>")
l.Add("ht", "ht")
l.Add("htt", "htt")
l.Add("ft", "ft")
l.Add("gi", "gi")
l.Add("ss", "ss")
l.Add("haha\nhaha\nhaha", "haha<br>haha<br>haha")
l.Add("//"+url, "<a rel='ugc' href='//"+url+"'>//"+url+"</a>")
l.Add("//a", "<a rel='ugc' href='//a'>//a</a>")
l.Add(" //a", " <a rel='ugc' href='//a'>//a</a>")
l.Add("//a ", "<a rel='ugc' href='//a'>//a</a> ")
l.Add(" //a ", " <a rel='ugc' href='//a'>//a</a> ")
l.Add("d //a ", "d <a rel='ugc' href='//a'>//a</a> ")
l.Add("ddd ddd //a ", "ddd ddd <a rel='ugc' href='//a'>//a</a> ")
l.Add("https://"+url, "<a rel='ugc' href='https://"+url+"'>https://"+url+"</a>")
l.Add("https://t", "<a href='https://t'>https://t</a>")
l.Add("http://"+url, "<a href='http://"+url+"'>http://"+url+"</a>")
l.Add("#http://"+url, "#http://"+url)
l.Add("@http://"+url, "<red>[Invalid Profile]</red>ttp://"+url)
l.Add("//"+url+"\n", "<a href='//"+url+"'>//"+url+"</a><br>")
l.Add("\n//"+url, "<br><a href='//"+url+"'>//"+url+"</a>")
l.Add("\n//"+url+"\n", "<br><a href='//"+url+"'>//"+url+"</a><br>")
l.Add("\n//"+url+"\n\n", "<br><a href='//"+url+"'>//"+url+"</a><br><br>")
l.Add("//"+url+"\n//"+url, "<a href='//"+url+"'>//"+url+"</a><br><a href='//"+url+"'>//"+url+"</a>")
l.Add("//"+url+"\n\n//"+url, "<a href='//"+url+"'>//"+url+"</a><br><br><a href='//"+url+"'>//"+url+"</a>")
l.Add("//"+c.Site.URL, "<a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a>")
l.Add("//"+c.Site.URL+"\n", "<a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a><br>")
l.Add("//"+c.Site.URL+"\n//"+c.Site.URL, "<a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a><br><a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a>")
var local = func(url string) {
msgList.Add("//"+url, "<a href='//"+url+"'>//"+url+"</a>")
msgList.Add("//"+url+"\n", "<a href='//"+url+"'>//"+url+"</a><br>")
msgList.Add("//"+url+"\n//"+url, "<a href='//"+url+"'>//"+url+"</a><br><a href='//"+url+"'>//"+url+"</a>")
local := func(url string) {
l.Add("//"+url, "<a href='//"+url+"'>//"+url+"</a>")
l.Add("//"+url+"\n", "<a href='//"+url+"'>//"+url+"</a><br>")
l.Add("//"+url+"\n//"+url, "<a href='//"+url+"'>//"+url+"</a><br><a href='//"+url+"'>//"+url+"</a>")
}
local("localhost")
local("127.0.0.1")
local("[::1]")
msgList.Add("https://www.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
//msgList.Add("https://www.youtube.com/watch?v=;","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/;' frameborder=0 allowfullscreen></iframe>")
msgList.Add("https://www.youtube.com/watch?v=d;","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/d' frameborder=0 allowfullscreen></iframe>")
msgList.Add("https://www.youtube.com/watch?v=d;d","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/d' frameborder=0 allowfullscreen></iframe>")
msgList.Add("https://www.youtube.com/watch?v=alert()","<red>[Invalid URL]</red>()")
msgList.Add("https://www.youtube.com/watch?v=js:alert()","<red>[Invalid URL]</red>()")
msgList.Add("https://www.youtube.com/watch?v='+><script>alert(\"\")</script><+'","<red>[Invalid URL]</red>'+><script>alert(\"\")</script><+'")
msgList.Add("https://www.youtube.com/watch?v='+onready='alert(\"\")'+'","<red>[Invalid URL]</red>'+onready='alert(\"\")'+'")
msgList.Add(" https://www.youtube.com/watch?v=lalalalala"," <iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
msgList.Add("https://www.youtube.com/watch?v=lalalalala tt","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe> tt")
msgList.Add("https://www.youtube.com/watch?v=lalalalala&d=haha","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
msgList.Add("https://gaming.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
msgList.Add("https://gaming.youtube.com/watch?v=lalalalala&d=haha","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
msgList.Add("https://m.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
msgList.Add("https://m.youtube.com/watch?v=lalalalala&d=haha","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
msgList.Add("http://www.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
msgList.Add("//www.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
//msgList.Add("www.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("https://www.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
//l.Add("https://www.youtube.com/watch?v=;","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/;' frameborder=0 allowfullscreen></iframe>")
l.Add("https://www.youtube.com/watch?v=d;","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/d' frameborder=0 allowfullscreen></iframe>")
l.Add("https://www.youtube.com/watch?v=d;d","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/d' frameborder=0 allowfullscreen></iframe>")
l.Add("https://www.youtube.com/watch?v=alert()","<red>[Invalid URL]</red>()")
l.Add("https://www.youtube.com/watch?v=alert()()","<red>[Invalid URL]</red>()()")
l.Add("https://www.youtube.com/watch?v=js:alert()","<red>[Invalid URL]</red>()")
l.Add("https://www.youtube.com/watch?v='+><script>alert(\"\")</script><+'","<red>[Invalid URL]</red>'+><script>alert(\"\")</script><+'")
l.Add("https://www.youtube.com/watch?v='+onready='alert(\"\")'+'","<red>[Invalid URL]</red>'+onready='alert(\"\")'+'")
l.Add(" https://www.youtube.com/watch?v=lalalalala"," <iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("https://www.youtube.com/watch?v=lalalalala tt","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe> tt")
l.Add("https://www.youtube.com/watch?v=lalalalala&d=haha","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("https://gaming.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("https://gaming.youtube.com/watch?v=lalalalala&d=haha","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("https://m.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("https://m.youtube.com/watch?v=lalalalala&d=haha","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("http://www.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("//www.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
//l.Add("www.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
msgList.Add("#tid-1", "<a href='/topic/1'>#tid-1</a>")
msgList.Add("##tid-1", "##tid-1")
msgList.Add("# #tid-1", "# #tid-1")
msgList.Add("@ #tid-1", "<red>[Invalid Profile]</red>#tid-1")
msgList.Add("@#tid-1", "<red>[Invalid Profile]</red>tid-1")
msgList.Add("@ #tid-@", "<red>[Invalid Profile]</red>#tid-@")
msgList.Add("#tid-1 #tid-1", "<a href='/topic/1'>#tid-1</a> <a href='/topic/1'>#tid-1</a>")
msgList.Add("#tid-0", "<red>[Invalid Topic]</red>")
msgList.Add("https://"+url+"/#tid-1", "<a href='https://"+url+"/#tid-1'>https://"+url+"/#tid-1</a>")
msgList.Add("https://"+url+"/?hi=2", "<a href='https://"+url+"/?hi=2'>https://"+url+"/?hi=2</a>")
msgList.Add("#fid-1", "<a href='/forum/1'>#fid-1</a>")
msgList.Add(" #fid-1", " <a href='/forum/1'>#fid-1</a>")
msgList.Add("#fid-0", "<red>[Invalid Forum]</red>")
msgList.Add(" #fid-0", " <red>[Invalid Forum]</red>")
msgList.Add("#", "#")
msgList.Add("# ", "# ")
msgList.Add(" @", " @")
msgList.Add(" #", " #")
msgList.Add("#@", "#@")
msgList.Add("#@ ", "#@ ")
msgList.Add("#@1", "#@1")
msgList.Add("#f", "#f")
msgList.Add("#ff", "#ff")
msgList.Add("#ffffid-0", "#ffffid-0")
//msgList.Add("#ffffid-0", "#ffffid-0")
msgList.Add("#nid-0", "#nid-0")
msgList.Add("#nnid-0", "#nnid-0")
msgList.Add("@@", "<red>[Invalid Profile]</red>")
msgList.Add("@@ @@", "<red>[Invalid Profile]</red> <red>[Invalid Profile]</red>")
msgList.Add("@@1", "<red>[Invalid Profile]</red>1")
msgList.Add("@#1", "<red>[Invalid Profile]</red>1")
msgList.Add("@##1", "<red>[Invalid Profile]</red>#1")
msgList.Add("@2", "<red>[Invalid Profile]</red>")
msgList.Add("@2t", "<red>[Invalid Profile]</red>t")
msgList.Add("@2 t", "<red>[Invalid Profile]</red> t")
msgList.Add("@2 ", "<red>[Invalid Profile]</red> ")
msgList.Add("@2 @2", "<red>[Invalid Profile]</red> <red>[Invalid Profile]</red>")
msgList.Add("@1", "<a href='/user/admin.1' class='mention'>@Admin</a>")
msgList.Add(" @1", " <a href='/user/admin.1' class='mention'>@Admin</a>")
msgList.Add("@1t", "<a href='/user/admin.1' class='mention'>@Admin</a>t")
msgList.Add("@1 ", "<a href='/user/admin.1' class='mention'>@Admin</a> ")
msgList.Add("@1 @1", "<a href='/user/admin.1' class='mention'>@Admin</a> <a href='/user/admin.1' class='mention'>@Admin</a>")
msgList.Add("@0", "<red>[Invalid Profile]</red>")
msgList.Add("@-1", "<red>[Invalid Profile]</red>1")
l.Add("#tid-1", "<a href='/topic/1'>#tid-1</a>")
l.Add("##tid-1", "##tid-1")
l.Add("# #tid-1", "# #tid-1")
l.Add("@ #tid-1", "<red>[Invalid Profile]</red>#tid-1")
l.Add("@#tid-1", "<red>[Invalid Profile]</red>tid-1")
l.Add("@ #tid-@", "<red>[Invalid Profile]</red>#tid-@")
l.Add("#tid-1 #tid-1", "<a href='/topic/1'>#tid-1</a> <a href='/topic/1'>#tid-1</a>")
l.Add("#tid-0", "<red>[Invalid Topic]</red>")
l.Add("https://"+url+"/#tid-1", "<a href='https://"+url+"/#tid-1'>https://"+url+"/#tid-1</a>")
l.Add("https://"+url+"/?hi=2", "<a href='https://"+url+"/?hi=2'>https://"+url+"/?hi=2</a>")
l.Add("#fid-1", "<a href='/forum/1'>#fid-1</a>")
l.Add(" #fid-1", " <a href='/forum/1'>#fid-1</a>")
l.Add("#fid-0", "<red>[Invalid Forum]</red>")
l.Add(" #fid-0", " <red>[Invalid Forum]</red>")
l.Add("#", "#")
l.Add("# ", "# ")
l.Add(" @", " @")
l.Add(" #", " #")
l.Add("#@", "#@")
l.Add("#@ ", "#@ ")
l.Add("#@1", "#@1")
l.Add("#f", "#f")
l.Add("f#f", "f#f")
l.Add("f#", "f#")
l.Add("#ff", "#ff")
l.Add("#ffffid-0", "#ffffid-0")
//l.Add("#ffffid-0", "#ffffid-0")
l.Add("#nid-0", "#nid-0")
l.Add("#nnid-0", "#nnid-0")
l.Add("@@", "<red>[Invalid Profile]</red>")
l.Add("@@ @@", "<red>[Invalid Profile]</red> <red>[Invalid Profile]</red>")
l.Add("@@1", "<red>[Invalid Profile]</red>1")
l.Add("@#1", "<red>[Invalid Profile]</red>1")
l.Add("@##1", "<red>[Invalid Profile]</red>#1")
l.Add("@2", "<red>[Invalid Profile]</red>")
l.Add("@2t", "<red>[Invalid Profile]</red>t")
l.Add("@2 t", "<red>[Invalid Profile]</red> t")
l.Add("@2 ", "<red>[Invalid Profile]</red> ")
l.Add("@2 @2", "<red>[Invalid Profile]</red> <red>[Invalid Profile]</red>")
l.Add("@1", "<a href='/user/admin.1' class='mention'>@Admin</a>")
l.Add(" @1", " <a href='/user/admin.1' class='mention'>@Admin</a>")
l.Add("@1t", "<a href='/user/admin.1' class='mention'>@Admin</a>t")
l.Add("@1 ", "<a href='/user/admin.1' class='mention'>@Admin</a> ")
l.Add("@1 @1", "<a href='/user/admin.1' class='mention'>@Admin</a> <a href='/user/admin.1' class='mention'>@Admin</a>")
l.Add("@0", "<red>[Invalid Profile]</red>")
l.Add("@-1", "<red>[Invalid Profile]</red>1")
for _, item := range msgList.Items {
for _, item := range l.Items {
res := c.ParseMessage(item.Msg, 1, "forums")
if res != item.Expects {
if item.Name != "" {

View File

@ -4,7 +4,7 @@ import (
"strconv"
"testing"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
)
// go test -v
@ -20,61 +20,61 @@ type MEPairList struct {
Items []MEPair
}
func (tlist *MEPairList) Add(msg string, expects string) {
tlist.Items = append(tlist.Items, MEPair{msg, expects})
func (l *MEPairList) Add(msg string, expects string) {
l.Items = append(l.Items, MEPair{msg, expects})
}
func TestBBCodeRender(t *testing.T) {
//t.Skip()
err := initBbcode(common.Plugins["bbcode"])
err := initBbcode(c.Plugins["bbcode"])
if err != nil {
t.Fatal(err)
}
var res string
var msgList = &MEPairList{nil}
msgList.Add("", "")
msgList.Add(" ", " ")
msgList.Add(" ", " ")
msgList.Add(" ", " ")
msgList.Add("[b]", "<b></b>")
msgList.Add("[b][/b]", "<b></b>")
msgList.Add("hi", "hi")
msgList.Add("😀", "😀")
msgList.Add("[b]😀[/b]", "<b>😀</b>")
msgList.Add("[b]😀😀😀[/b]", "<b>😀😀😀</b>")
msgList.Add("[b]hi[/b]", "<b>hi</b>")
msgList.Add("[u]hi[/u]", "<u>hi</u>")
msgList.Add("[i]hi[/i]", "<i>hi</i>")
msgList.Add("[s]hi[/s]", "<s>hi</s>")
msgList.Add("[c]hi[/c]", "[c]hi[/c]")
msgList.Add("[h1]hi", "[h1]hi")
msgList.Add("[h1]hi[/h1]", "<h2>hi</h2>")
l := &MEPairList{nil}
l.Add("", "")
l.Add(" ", " ")
l.Add(" ", " ")
l.Add(" ", " ")
l.Add("[b]", "<b></b>")
l.Add("[b][/b]", "<b></b>")
l.Add("hi", "hi")
l.Add("😀", "😀")
l.Add("[b]😀[/b]", "<b>😀</b>")
l.Add("[b]😀😀😀[/b]", "<b>😀😀😀</b>")
l.Add("[b]hi[/b]", "<b>hi</b>")
l.Add("[u]hi[/u]", "<u>hi</u>")
l.Add("[i]hi[/i]", "<i>hi</i>")
l.Add("[s]hi[/s]", "<s>hi</s>")
l.Add("[c]hi[/c]", "[c]hi[/c]")
l.Add("[h1]hi", "[h1]hi")
l.Add("[h1]hi[/h1]", "<h2>hi</h2>")
if !testing.Short() {
//msgList.Add("[b]hi[/i]", "[b]hi[/i]")
//msgList.Add("[/b]hi[b]", "[/b]hi[b]")
//msgList.Add("[/b]hi[/b]", "[/b]hi[/b]")
//msgList.Add("[b][b]hi[/b]", "<b>hi</b>")
//msgList.Add("[b][b]hi", "[b][b]hi")
//msgList.Add("[b][b][b]hi", "[b][b][b]hi")
//msgList.Add("[/b]hi", "[/b]hi")
//l.Add("[b]hi[/i]", "[b]hi[/i]")
//l.Add("[/b]hi[b]", "[/b]hi[b]")
//l.Add("[/b]hi[/b]", "[/b]hi[/b]")
//l.Add("[b][b]hi[/b]", "<b>hi</b>")
//l.Add("[b][b]hi", "[b][b]hi")
//l.Add("[b][b][b]hi", "[b][b][b]hi")
//l.Add("[/b]hi", "[/b]hi")
}
msgList.Add("[code]hi[/code]", "<span class='codequotes'>hi</span>")
msgList.Add("[code][b]hi[/b][/code]", "<span class='codequotes'>[b]hi[/b]</span>")
msgList.Add("[code][b]hi[/code][/b]", "<span class='codequotes'>[b]hi</span>[/b]")
msgList.Add("[quote]hi[/quote]", "<blockquote>hi</blockquote>")
msgList.Add("[quote][b]hi[/b][/quote]", "<blockquote><b>hi</b></blockquote>")
msgList.Add("[quote][b]h[/b][/quote]", "<blockquote><b>h</b></blockquote>")
msgList.Add("[quote][b][/b][/quote]", "<blockquote><b></b></blockquote>")
msgList.Add("[url][/url]", "<a href=''></a>")
msgList.Add("[url]https://github.com/Azareal/Gosora[/url]", "<a href='https://github.com/Azareal/Gosora'>https://github.com/Azareal/Gosora</a>")
msgList.Add("[url]http://github.com/Azareal/Gosora[/url]", "<a href='http://github.com/Azareal/Gosora'>http://github.com/Azareal/Gosora</a>")
msgList.Add("[url]//github.com/Azareal/Gosora[/url]", "<a href='//github.com/Azareal/Gosora'>//github.com/Azareal/Gosora</a>")
msgList.Add("-你好-", "-你好-")
msgList.Add("[i]-你好-[/i]", "<i>-你好-</i>") // TODO: More of these Unicode tests? Emoji, Chinese, etc.?
l.Add("[code]hi[/code]", "<span class='codequotes'>hi</span>")
l.Add("[code][b]hi[/b][/code]", "<span class='codequotes'>[b]hi[/b]</span>")
l.Add("[code][b]hi[/code][/b]", "<span class='codequotes'>[b]hi</span>[/b]")
l.Add("[quote]hi[/quote]", "<blockquote>hi</blockquote>")
l.Add("[quote][b]hi[/b][/quote]", "<blockquote><b>hi</b></blockquote>")
l.Add("[quote][b]h[/b][/quote]", "<blockquote><b>h</b></blockquote>")
l.Add("[quote][b][/b][/quote]", "<blockquote><b></b></blockquote>")
l.Add("[url][/url]", "<a href=''></a>")
l.Add("[url]https://github.com/Azareal/Gosora[/url]", "<a href='https://github.com/Azareal/Gosora'>https://github.com/Azareal/Gosora</a>")
l.Add("[url]http://github.com/Azareal/Gosora[/url]", "<a href='http://github.com/Azareal/Gosora'>http://github.com/Azareal/Gosora</a>")
l.Add("[url]//github.com/Azareal/Gosora[/url]", "<a href='//github.com/Azareal/Gosora'>//github.com/Azareal/Gosora</a>")
l.Add("-你好-", "-你好-")
l.Add("[i]-你好-[/i]", "<i>-你好-</i>") // TODO: More of these Unicode tests? Emoji, Chinese, etc.?
t.Log("Testing bbcodeFullParse")
for _, item := range msgList.Items {
for _, item := range l.Items {
res = bbcodeFullParse(item.Msg)
if res != item.Expects {
t.Error("Testing string '" + item.Msg + "'")
@ -83,77 +83,26 @@ func TestBBCodeRender(t *testing.T) {
}
}
var msg string
var expects string
msg = "[rand][/rand]"
expects = "<red>[Invalid Number]</red>[rand][/rand]"
f := func(msg, expects string) {
t.Log("Testing string '" + msg + "'")
res = bbcodeFullParse(msg)
res := bbcodeFullParse(msg)
if res != expects {
t.Error("Bad output:", "'"+res+"'")
t.Error("Expected:", "'"+expects+"'")
}
msg = "[rand]-1[/rand]"
expects = "<red>[No Negative Numbers]</red>[rand]-1[/rand]"
t.Log("Testing string '" + msg + "'")
res = bbcodeFullParse(msg)
if res != expects {
t.Error("Bad output:", "'"+res+"'")
t.Error("Expected:", "'"+expects+"'")
}
f("[rand][/rand]","<red>[Invalid Number]</red>[rand][/rand]")
f("[rand]-1[/rand]","<red>[No Negative Numbers]</red>[rand]-1[/rand]")
f("[rand]-01[/rand]","<red>[No Negative Numbers]</red>[rand]-01[/rand]")
f("[rand]NaN[/rand]","<red>[Invalid Number]</red>[rand]NaN[/rand]")
f("[rand]Inf[/rand]","<red>[Invalid Number]</red>[rand]Inf[/rand]")
f("[rand]+[/rand]","<red>[Invalid Number]</red>[rand]+[/rand]")
f("[rand]1+1[/rand]","<red>[Invalid Number]</red>[rand]1+1[/rand]")
msg = "[rand]-01[/rand]"
expects = "<red>[No Negative Numbers]</red>[rand]-01[/rand]"
msg := "[rand]1[/rand]"
t.Log("Testing string '" + msg + "'")
res = bbcodeFullParse(msg)
if res != expects {
t.Error("Bad output:", "'"+res+"'")
t.Error("Expected:", "'"+expects+"'")
}
msg = "[rand]NaN[/rand]"
expects = "<red>[Invalid Number]</red>[rand]NaN[/rand]"
t.Log("Testing string '" + msg + "'")
res = bbcodeFullParse(msg)
if res != expects {
t.Error("Bad output:", "'"+res+"'")
t.Error("Expected:", "'"+expects+"'")
}
msg = "[rand]Inf[/rand]"
expects = "<red>[Invalid Number]</red>[rand]Inf[/rand]"
t.Log("Testing string '" + msg + "'")
res = bbcodeFullParse(msg)
if res != expects {
t.Error("Bad output:", "'"+res+"'")
t.Error("Expected:", "'"+expects+"'")
}
msg = "[rand]+[/rand]"
expects = "<red>[Invalid Number]</red>[rand]+[/rand]"
t.Log("Testing string '" + msg + "'")
res = bbcodeFullParse(msg)
if res != expects {
t.Error("Bad output:", "'"+res+"'")
t.Error("Expected:", "'"+expects+"'")
}
msg = "[rand]1+1[/rand]"
expects = "<red>[Invalid Number]</red>[rand]1+1[/rand]"
t.Log("Testing string '" + msg + "'")
res = bbcodeFullParse(msg)
if res != expects {
t.Error("Bad output:", "'"+res+"'")
t.Error("Expected:", "'"+expects+"'")
}
var conv int
msg = "[rand]1[/rand]"
t.Log("Testing string '" + msg + "'")
res = bbcodeFullParse(msg)
conv, err = strconv.Atoi(res)
conv, err := strconv.Atoi(res)
if err != nil || (conv > 1 || conv < 0) {
t.Error("Bad output:", "'"+res+"'")
t.Error("Expected a number in the range 0-1")
@ -205,7 +154,7 @@ func TestBBCodeRender(t *testing.T) {
}
/*t.Log("Testing bbcode_regex_parse")
for _, item := range msgList {
for _, item := range l.Items {
t.Log("Testing string '" + item.Msg + "'")
res = bbcodeRegexParse(item.Msg)
if res != item.Expects {
@ -217,94 +166,92 @@ func TestBBCodeRender(t *testing.T) {
func TestMarkdownRender(t *testing.T) {
//t.Skip()
err := initMarkdown(common.Plugins["markdown"])
err := initMarkdown(c.Plugins["markdown"])
if err != nil {
t.Fatal(err)
}
var res string
var msgList = &MEPairList{nil}
var msgList2 = &MEPairList{nil}
l := &MEPairList{nil}
l2 := &MEPairList{nil}
// TODO: Fix more of these odd cases
msgList.Add("", "")
msgList.Add(" ", " ")
msgList.Add(" ", " ")
msgList.Add(" ", " ")
msgList.Add("\t", "\t")
msgList.Add("\n", "\n")
msgList.Add("*", "*")
msgList.Add("`", "`")
//msgList.Add("**", "<i></i>")
msgList.Add("h", "h")
msgList.Add("hi", "hi")
msgList.Add("**h**", "<b>h</b>")
msgList.Add("**hi**", "<b>hi</b>")
msgList.Add("_h_", "<u>h</u>")
msgList.Add("_hi_", "<u>hi</u>")
msgList.Add("*h*", "<i>h</i>")
msgList.Add("*hi*", "<i>hi</i>")
msgList.Add("~h~", "<s>h</s>")
msgList.Add("~hi~", "<s>hi</s>")
msgList.Add("`hi`", "<blockquote>hi</blockquote>")
l.Add("", "")
l.Add(" ", " ")
l.Add(" ", " ")
l.Add(" ", " ")
l.Add("\t", "\t")
l.Add("\n", "\n")
l.Add("*", "*")
l.Add("`", "`")
//l.Add("**", "<i></i>")
l.Add("h", "h")
l.Add("hi", "hi")
l.Add("**h**", "<b>h</b>")
l.Add("**hi**", "<b>hi</b>")
l.Add("_h_", "<u>h</u>")
l.Add("_hi_", "<u>hi</u>")
l.Add("*h*", "<i>h</i>")
l.Add("*hi*", "<i>hi</i>")
l.Add("~h~", "<s>h</s>")
l.Add("~hi~", "<s>hi</s>")
l.Add("`hi`", "<blockquote>hi</blockquote>")
// TODO: Hide the backslash after escaping the item
// TODO: Doesn't behave consistently with d in-front of it
msgList2.Add("\\`hi`", "\\`hi`")
msgList2.Add("#", "#")
msgList2.Add("#h", "<h2>h</h2>")
msgList2.Add("#hi", "<h2>hi</h2>")
msgList2.Add("# hi", "<h2>hi</h2>")
msgList2.Add("# hi", "<h2>hi</h2>")
msgList.Add("\n#", "\n#")
msgList.Add("\n#h", "\n<h2>h</h2>")
msgList.Add("\n#hi", "\n<h2>hi</h2>")
msgList.Add("\n#h\n", "\n<h2>h</h2>")
msgList.Add("\n#hi\n", "\n<h2>hi</h2>")
msgList.Add("*hi**", "<i>hi</i>*")
msgList.Add("**hi***", "<b>hi</b>*")
//msgList.Add("**hi*", "*<i>hi</i>")
msgList.Add("***hi***", "<b><i>hi</i></b>")
msgList.Add("***h***", "<b><i>h</i></b>")
msgList.Add("\\***h**\\*", "*<b>h</b>*")
msgList.Add("\\*\\**h*\\*\\*", "**<i>h</i>**")
msgList.Add("\\*hi\\*", "*hi*")
msgList.Add("d\\*hi\\*", "d*hi*")
msgList.Add("\\*hi\\*d", "*hi*d")
msgList.Add("d\\*hi\\*d", "d*hi*d")
msgList.Add("\\", "\\")
msgList.Add("\\\\", "\\\\")
msgList.Add("\\d", "\\d")
msgList.Add("\\\\d", "\\\\d")
msgList.Add("\\\\\\d", "\\\\\\d")
msgList.Add("d\\", "d\\")
msgList.Add("\\d\\", "\\d\\")
msgList.Add("*_hi_*", "<i><u>hi</u></i>")
msgList.Add("*~hi~*", "<i><s>hi</s></i>")
//msgList.Add("~*hi*~", "<s><i>hi</i></s>")
//msgList.Add("~ *hi* ~", "<s> <i>hi</i> </s>")
msgList.Add("_~hi~_", "<u><s>hi</s></u>")
msgList.Add("***~hi~***", "<b><i><s>hi</s></i></b>")
msgList.Add("**", "**")
msgList.Add("***", "***")
msgList.Add("****", "****")
msgList.Add("*****", "*****")
msgList.Add("******", "******")
msgList.Add("*******", "*******")
msgList.Add("~~", "~~")
msgList.Add("~~~", "~~~")
msgList.Add("~~~~", "~~~~")
msgList.Add("~~~~~", "~~~~~")
msgList.Add("__", "__")
msgList.Add("___", "___")
msgList.Add("_ _", "<u> </u>")
msgList.Add("* *", "<i> </i>")
msgList.Add("** **", "<b> </b>")
msgList.Add("*** ***", "<b><i> </i></b>")
msgList.Add("-你好-", "-你好-")
msgList.Add("*-你好-*", "<i>-你好-</i>") // TODO: More of these Unicode tests? Emoji, Chinese, etc.?
l2.Add("\\`hi`", "\\`hi`")
l2.Add("#", "#")
l2.Add("#h", "<h2>h</h2>")
l2.Add("#hi", "<h2>hi</h2>")
l2.Add("# hi", "<h2>hi</h2>")
l2.Add("# hi", "<h2>hi</h2>")
l.Add("\n#", "\n#")
l.Add("\n#h", "\n<h2>h</h2>")
l.Add("\n#hi", "\n<h2>hi</h2>")
l.Add("\n#h\n", "\n<h2>h</h2>")
l.Add("\n#hi\n", "\n<h2>hi</h2>")
l.Add("*hi**", "<i>hi</i>*")
l.Add("**hi***", "<b>hi</b>*")
//l.Add("**hi*", "*<i>hi</i>")
l.Add("***hi***", "<b><i>hi</i></b>")
l.Add("***h***", "<b><i>h</i></b>")
l.Add("\\***h**\\*", "*<b>h</b>*")
l.Add("\\*\\**h*\\*\\*", "**<i>h</i>**")
l.Add("\\*hi\\*", "*hi*")
l.Add("d\\*hi\\*", "d*hi*")
l.Add("\\*hi\\*d", "*hi*d")
l.Add("d\\*hi\\*d", "d*hi*d")
l.Add("\\", "\\")
l.Add("\\\\", "\\\\")
l.Add("\\d", "\\d")
l.Add("\\\\d", "\\\\d")
l.Add("\\\\\\d", "\\\\\\d")
l.Add("d\\", "d\\")
l.Add("\\d\\", "\\d\\")
l.Add("*_hi_*", "<i><u>hi</u></i>")
l.Add("*~hi~*", "<i><s>hi</s></i>")
//l.Add("~*hi*~", "<s><i>hi</i></s>")
//l.Add("~ *hi* ~", "<s> <i>hi</i> </s>")
l.Add("_~hi~_", "<u><s>hi</s></u>")
l.Add("***~hi~***", "<b><i><s>hi</s></i></b>")
l.Add("**", "**")
l.Add("***", "***")
l.Add("****", "****")
l.Add("*****", "*****")
l.Add("******", "******")
l.Add("*******", "*******")
l.Add("~~", "~~")
l.Add("~~~", "~~~")
l.Add("~~~~", "~~~~")
l.Add("~~~~~", "~~~~~")
l.Add("__", "__")
l.Add("___", "___")
l.Add("_ _", "<u> </u>")
l.Add("* *", "<i> </i>")
l.Add("** **", "<b> </b>")
l.Add("*** ***", "<b><i> </i></b>")
l.Add("-你好-", "-你好-")
l.Add("*-你好-*", "<i>-你好-</i>") // TODO: More of these Unicode tests? Emoji, Chinese, etc.?
for _, item := range msgList.Items {
res = markdownParse(item.Msg)
if res != item.Expects {
for _, item := range l.Items {
if res := markdownParse(item.Msg); res != item.Expects {
t.Error("Testing string '" + item.Msg + "'")
t.Error("Bad output:", "'"+res+"'")
//t.Error("Ouput in bytes:", []byte(res))
@ -312,9 +259,8 @@ func TestMarkdownRender(t *testing.T) {
}
}
for _, item := range msgList2.Items {
res = markdownParse(item.Msg)
if res != item.Expects {
for _, item := range l2.Items {
if res := markdownParse(item.Msg); res != item.Expects {
t.Error("Testing string '" + item.Msg + "'")
t.Error("Bad output:", "'"+res+"'")
//t.Error("Ouput in bytes:", []byte(res))
@ -322,9 +268,8 @@ func TestMarkdownRender(t *testing.T) {
}
}
/*for _, item := range msgList.Items {
res = markdownParse("\n" + item.Msg)
if res != "\n"+item.Expects {
/*for _, item := range l.Items {
if res := markdownParse("\n" + item.Msg); res != "\n"+item.Expects {
t.Error("Testing string '\n" + item.Msg + "'")
t.Error("Bad output:", "'"+res+"'")
//t.Error("Ouput in bytes:", []byte(res))
@ -332,9 +277,8 @@ func TestMarkdownRender(t *testing.T) {
}
}
for _, item := range msgList.Items {
res = markdownParse("\t" + item.Msg)
if res != "\t"+item.Expects {
for _, item := range l.Items {
if res := markdownParse("\t" + item.Msg); res != "\t"+item.Expects {
t.Error("Testing string '\t" + item.Msg + "'")
t.Error("Bad output:", "'"+res+"'")
//t.Error("Ouput in bytes:", []byte(res))
@ -342,9 +286,8 @@ func TestMarkdownRender(t *testing.T) {
}
}*/
for _, item := range msgList.Items {
res = markdownParse("d" + item.Msg)
if res != "d"+item.Expects {
for _, item := range l.Items {
if res := markdownParse("d" + item.Msg); res != "d"+item.Expects {
t.Error("Testing string 'd" + item.Msg + "'")
t.Error("Bad output:", "'"+res+"'")
//t.Error("Ouput in bytes:", []byte(res))

View File

@ -13,19 +13,19 @@ import (
"strings"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/phrases"
p "github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen"
)
// A blank list to fill out that parameter in Page for routes which don't use it
var tList []interface{}
func AccountLogin(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
func AccountLogin(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
if user.Loggedin {
return c.LocalError("You're already logged in.", w, r, user)
}
header.Title = phrases.GetTitlePhrase("login")
return renderTemplate("login", w, r, header, c.Page{header, tList, nil})
h.Title = p.GetTitlePhrase("login")
return renderTemplate("login", w, r, h, c.Page{h, tList, nil})
}
// TODO: Log failed attempted logins?
@ -141,11 +141,11 @@ func mfaVerifySession(provSession string, signedSession string, uid int) bool {
return subtle.ConstantTimeCompare([]byte(signedSession), []byte(expected)) == 1
}
func AccountLoginMFAVerify(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
func AccountLoginMFAVerify(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
if user.Loggedin {
return c.LocalError("You're already logged in.", w, r, user)
}
header.Title = phrases.GetTitlePhrase("login_mfa_verify")
h.Title = p.GetTitlePhrase("login_mfa_verify")
uid, provSession, signedSession, err := mfaGetCookies(r)
if err != nil {
@ -155,7 +155,7 @@ func AccountLoginMFAVerify(w http.ResponseWriter, r *http.Request, user c.User,
return c.LocalError("Invalid session", w, r, user)
}
return renderTemplate("login_mfa_verify", w, r, header, c.Page{header, tList, nil})
return renderTemplate("login_mfa_verify", w, r, h, c.Page{h, tList, nil})
}
func AccountLoginMFAVerifySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
@ -182,13 +182,13 @@ func AccountLogout(w http.ResponseWriter, r *http.Request, user c.User) c.RouteE
return nil
}
func AccountRegister(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
func AccountRegister(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
if user.Loggedin {
return c.LocalError("You're already logged in.", w, r, user)
}
header.Title = phrases.GetTitlePhrase("register")
header.AddScriptAsync("register.js")
return renderTemplate("register", w, r, header, c.Page{header, tList, nil})
h.Title = p.GetTitlePhrase("register")
h.AddScriptAsync("register.js")
return renderTemplate("register", w, r, h, c.Page{h, tList, nil})
}
func isNumeric(data string) (numeric bool) {
@ -204,10 +204,10 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user c.User)
headerLite, _ := c.SimpleUserCheck(w, r, &user)
// TODO: Should we push multiple validation errors to the user instead of just one?
var regSuccess = true
var regErrMsg = ""
var regErrReason = ""
var regError = func(userMsg string, reason string) {
regSuccess := true
regErrMsg := ""
regErrReason := ""
regError := func(userMsg string, reason string) {
regSuccess = false
if regErrMsg == "" {
regErrMsg = userMsg
@ -216,14 +216,14 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user c.User)
}
if r.PostFormValue("tos") != "0" {
regError(phrases.GetErrorPhrase("register_might_be_machine"), "trap-question")
regError(p.GetErrorPhrase("register_might_be_machine"), "trap-question")
}
if !c.Config.DisableJSAntispam {
h := sha256.New()
h.Write([]byte(c.JSTokenBox.Load().(string)))
h.Write([]byte(user.LastIP))
if r.PostFormValue("golden-watch") != hex.EncodeToString(h.Sum(nil)) {
regError(phrases.GetErrorPhrase("register_might_be_machine"), "js-antispam")
regError(p.GetErrorPhrase("register_might_be_machine"), "js-antispam")
}
}
@ -231,21 +231,20 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user c.User)
// TODO: Add a dedicated function for validating emails
email := c.SanitiseSingleLine(r.PostFormValue("email"))
if username == "" {
regError(phrases.GetErrorPhrase("register_need_username"), "no-username")
regError(p.GetErrorPhrase("register_need_username"), "no-username")
}
if email == "" {
regError(phrases.GetErrorPhrase("register_need_email"), "no-email")
regError(p.GetErrorPhrase("register_need_email"), "no-email")
}
// This is so a numeric name won't interfere with mentioning a user by ID, there might be a better way of doing this like perhaps !@ to mean IDs and @ to mean usernames in the pre-parser
usernameBits := strings.Split(username, " ")
if isNumeric(usernameBits[0]) {
regError(phrases.GetErrorPhrase("register_first_word_numeric"), "numeric-name")
regError(p.GetErrorPhrase("register_first_word_numeric"), "numeric-name")
}
ok := c.HasSuspiciousEmail(email)
if ok {
regError(phrases.GetErrorPhrase("register_suspicious_email"), "suspicious-email")
if c.HasSuspiciousEmail(email) {
regError(p.GetErrorPhrase("register_suspicious_email"), "suspicious-email")
}
password := r.PostFormValue("password")
@ -257,7 +256,7 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user c.User)
// Do the two inputted passwords match..?
confirmPassword := r.PostFormValue("confirm_password")
if password != confirmPassword {
regError(phrases.GetErrorPhrase("register_password_mismatch"), "password-mismatch")
regError(p.GetErrorPhrase("register_password_mismatch"), "password-mismatch")
}
}
@ -290,14 +289,14 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user c.User)
if err != nil {
return c.InternalError(err, w, r)
}
return c.LocalError(phrases.GetErrorPhrase("register_username_unavailable"), w, r, user)
return c.LocalError(p.GetErrorPhrase("register_username_unavailable"), w, r, user)
} else if err == c.ErrLongUsername {
regLog.FailureReason += "username-too-long"
err = regLog.Commit()
if err != nil {
return c.InternalError(err, w, r)
}
return c.LocalError(phrases.GetErrorPhrase("register_username_too_long_prefix")+strconv.Itoa(c.Config.MaxUsernameLength), w, r, user)
return c.LocalError(p.GetErrorPhrase("register_username_too_long_prefix")+strconv.Itoa(c.Config.MaxUsernameLength), w, r, user)
}
regLog.FailureReason += "internal-error"
err2 := regLog.Commit()
@ -328,7 +327,7 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user c.User)
err = c.SendValidationEmail(username, email, token)
if err != nil {
return c.LocalError(phrases.GetErrorPhrase("register_email_fail"), w, r, user)
return c.LocalError(p.GetErrorPhrase("register_email_fail"), w, r, user)
}
}
@ -337,11 +336,11 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user c.User)
}
// TODO: Figure a way of making this into middleware?
func accountEditHead(titlePhrase string, w http.ResponseWriter, r *http.Request, user *c.User, header *c.Header) {
header.Title = phrases.GetTitlePhrase(titlePhrase)
header.Path = "/user/edit/"
header.AddSheet(header.Theme.Name + "/account.css")
header.AddScriptAsync("account.js")
func accountEditHead(titlePhrase string, w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) {
h.Title = p.GetTitlePhrase(titlePhrase)
h.Path = "/user/edit/"
h.AddSheet(h.Theme.Name + "/account.css")
h.AddScriptAsync("account.js")
}
func AccountEdit(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
@ -356,7 +355,7 @@ func AccountEdit(w http.ResponseWriter, r *http.Request, user c.User, header *c.
}
// TODO: Find a more efficient way of doing this
var mfaSetup = false
mfaSetup := false
_, err := c.MFAstore.Get(user.ID)
if err != sql.ErrNoRows && err != nil {
return c.InternalError(err, w, r)
@ -375,9 +374,9 @@ func AccountEdit(w http.ResponseWriter, r *http.Request, user c.User, header *c.
}
//edit_password
func AccountEditPassword(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
accountEditHead("account_password", w, r, &user, header)
return renderTemplate("account_own_edit_password", w, r, header, c.Page{header, tList, nil})
func AccountEditPassword(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
accountEditHead("account_password", w, r, &user, h)
return renderTemplate("account_own_edit_password", w, r, h, c.Page{h, tList, nil})
}
// TODO: Require re-authentication if the user hasn't logged in in a while
@ -479,8 +478,8 @@ func AccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, user c.Us
return nil
}
func AccountEditMFA(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
accountEditHead("account_mfa", w, r, &user, header)
func AccountEditMFA(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
accountEditHead("account_mfa", w, r, &user, h)
mfaItem, err := c.MFAstore.Get(user.ID)
if err != sql.ErrNoRows && err != nil {
@ -489,13 +488,13 @@ func AccountEditMFA(w http.ResponseWriter, r *http.Request, user c.User, header
return c.LocalError("Two-factor authentication hasn't been setup on your account", w, r, user)
}
pi := c.Page{header, tList, mfaItem.Scratch}
return renderTemplate("account_own_edit_mfa", w, r, header, pi)
pi := c.Page{h, tList, mfaItem.Scratch}
return renderTemplate("account_own_edit_mfa", w, r, h, pi)
}
// If not setup, generate a string, otherwise give an option to disable mfa given the right code
func AccountEditMFASetup(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
accountEditHead("account_mfa_setup", w, r, &user, header)
func AccountEditMFASetup(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
accountEditHead("account_mfa_setup", w, r, &user, h)
// Flash an error if mfa is already setup
_, err := c.MFAstore.Get(user.ID)
@ -511,8 +510,8 @@ func AccountEditMFASetup(w http.ResponseWriter, r *http.Request, user c.User, he
return c.InternalError(err, w, r)
}
pi := c.Page{header, tList, c.FriendlyGAuthSecret(code)}
return renderTemplate("account_own_edit_mfa_setup", w, r, header, pi)
pi := c.Page{h, tList, c.FriendlyGAuthSecret(code)}
return renderTemplate("account_own_edit_mfa_setup", w, r, h, pi)
}
// Form should bounce the random mfa secret back and the otp to be verified server-side to reduce the chances of a bug arising on the JS side which makes every code mismatch
@ -530,8 +529,8 @@ func AccountEditMFASetupSubmit(w http.ResponseWriter, r *http.Request, user c.Us
return c.LocalError("You have already setup two-factor authentication", w, r, user)
}
var code = r.PostFormValue("code")
var otp = r.PostFormValue("otp")
code := r.PostFormValue("code")
otp := r.PostFormValue("otp")
ok, err := c.VerifyGAuthToken(code, otp)
if err != nil {
//fmt.Println("err: ", err)
@ -576,8 +575,8 @@ func AccountEditMFADisableSubmit(w http.ResponseWriter, r *http.Request, user c.
return nil
}
func AccountEditEmail(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
accountEditHead("account_email", w, r, &user, header)
func AccountEditEmail(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
accountEditHead("account_email", w, r, &user, h)
emails, err := c.Emails.GetEmailsByUser(&user)
if err != nil {
return c.InternalError(err, w, r)
@ -586,22 +585,18 @@ func AccountEditEmail(w http.ResponseWriter, r *http.Request, user c.User, heade
// Was this site migrated from another forum software? Most of them don't have multiple emails for a single user.
// This also applies when the admin switches site.EnableEmails on after having it off for a while.
if len(emails) == 0 {
email := c.Email{UserID: user.ID}
email.Email = user.Email
email.Validated = false
email.Primary = true
emails = append(emails, email)
emails = append(emails, c.Email{UserID: user.ID, Email: user.Email, Validated: false, Primary: true})
}
if !c.Site.EnableEmails {
header.AddNotice("account_mail_disabled")
h.AddNotice("account_mail_disabled")
}
if r.FormValue("verified") == "1" {
header.AddNotice("account_mail_verify_success")
h.AddNotice("account_mail_verify_success")
}
pi := c.Account{header, "edit_emails", "account_own_edit_email", c.EmailListPage{header, emails}}
return renderTemplate("account", w, r, header, pi)
pi := c.Account{h, "edit_emails", "account_own_edit_email", c.EmailListPage{h, emails}}
return renderTemplate("account", w, r, h, pi)
}
// TODO: Should we make this an AnonAction so someone can do this without being logged in?
@ -649,9 +644,8 @@ func AccountEditEmailTokenSubmit(w http.ResponseWriter, r *http.Request, user c.
return nil
}
func AccountLogins(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
accountEditHead("account_logins", w, r, &user, header)
func AccountLogins(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
accountEditHead("account_logins", w, r, &user, h)
logCount := c.LoginLogs.CountUser(user.ID)
page, _ := strconv.Atoi(r.FormValue("page"))
perPage := 12
@ -663,15 +657,15 @@ func AccountLogins(w http.ResponseWriter, r *http.Request, user c.User, header *
}
pageList := c.Paginate(page, lastPage, 5)
pi := c.Account{header, "logins", "account_logins", c.AccountLoginsPage{header, logs, c.Paginator{pageList, page, lastPage}}}
return renderTemplate("account", w, r, header, pi)
pi := c.Account{h, "logins", "account_logins", c.AccountLoginsPage{h, logs, c.Paginator{pageList, page, lastPage}}}
return renderTemplate("account", w, r, h, pi)
}
func LevelList(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
header.Title = phrases.GetTitlePhrase("account_level_list")
func LevelList(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
h.Title = p.GetTitlePhrase("account_level_list")
var fScores = c.GetLevels(20)
var levels = make([]c.LevelListItem, len(fScores))
fScores := c.GetLevels(20)
levels := make([]c.LevelListItem, len(fScores))
for i, fScore := range fScores {
var status string
if user.Level > i {
@ -686,25 +680,25 @@ func LevelList(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
levels[i] = c.LevelListItem{i, iScore, status, perc * 2}
}
return renderTemplate("level_list", w, r, header, c.LevelListPage{header, levels[1:]})
return renderTemplate("level_list", w, r, h, c.LevelListPage{h, levels[1:]})
}
func Alerts(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
func Alerts(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
return nil
}
func AccountPasswordReset(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
func AccountPasswordReset(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
if user.Loggedin {
return c.LocalError("You're already logged in.", w, r, user)
}
if !c.Site.EnableEmails {
return c.LocalError(phrases.GetNoticePhrase("account_mail_disabled"), w, r, user)
return c.LocalError(p.GetNoticePhrase("account_mail_disabled"), w, r, user)
}
if r.FormValue("email_sent") == "1" {
header.AddNotice("password_reset_email_sent")
h.AddNotice("password_reset_email_sent")
}
header.Title = phrases.GetTitlePhrase("password_reset")
return renderTemplate("password_reset", w, r, header, c.Page{header, tList, nil})
h.Title = p.GetTitlePhrase("password_reset")
return renderTemplate("password_reset", w, r, h, c.Page{h, tList, nil})
}
// TODO: Ratelimit this
@ -713,7 +707,7 @@ func AccountPasswordResetSubmit(w http.ResponseWriter, r *http.Request, user c.U
return c.LocalError("You're already logged in.", w, r, user)
}
if !c.Site.EnableEmails {
return c.LocalError(phrases.GetNoticePhrase("account_mail_disabled"), w, r, user)
return c.LocalError(p.GetNoticePhrase("account_mail_disabled"), w, r, user)
}
username := r.PostFormValue("username")
@ -767,9 +761,9 @@ func AccountPasswordResetSubmit(w http.ResponseWriter, r *http.Request, user c.U
schema = "s"
}
err = c.SendEmail(tuser.Email, phrases.GetTmplPhrase("password_reset_subject"), phrases.GetTmplPhrasef("password_reset_body", tuser.Name, "http"+schema+"://"+c.Site.URL+"/accounts/password-reset/token/?uid="+strconv.Itoa(tuser.ID)+"&token="+token))
err = c.SendEmail(tuser.Email, p.GetTmplPhrase("password_reset_subject"), p.GetTmplPhrasef("password_reset_body", tuser.Name, "http"+schema+"://"+c.Site.URL+"/accounts/password-reset/token/?uid="+strconv.Itoa(tuser.ID)+"&token="+token))
if err != nil {
return c.LocalError(phrases.GetErrorPhrase("password_reset_email_fail"), w, r, user)
return c.LocalError(p.GetErrorPhrase("password_reset_email_fail"), w, r, user)
}
http.Redirect(w, r, "/accounts/password-reset/?email_sent=1", http.StatusSeeOther)
@ -804,7 +798,7 @@ func AccountPasswordResetToken(w http.ResponseWriter, r *http.Request, user c.Us
}
mfa := err != sql.ErrNoRows
header.Title = phrases.GetTitlePhrase("password_reset_token")
header.Title = p.GetTitlePhrase("password_reset_token")
return renderTemplate("password_reset_token", w, r, header, c.ResetPage{header, uid, html.EscapeString(token), mfa})
}
@ -812,8 +806,6 @@ func AccountPasswordResetTokenSubmit(w http.ResponseWriter, r *http.Request, use
if user.Loggedin {
return c.LocalError("You're already logged in.", w, r, user)
}
token := r.FormValue("token")
uid, err := strconv.Atoi(r.FormValue("uid"))
if err != nil {
return c.LocalError("Invalid uid", w, r, user)
@ -822,6 +814,7 @@ func AccountPasswordResetTokenSubmit(w http.ResponseWriter, r *http.Request, use
return c.LocalError("This reset token has expired.", w, r, user)
}
token := r.FormValue("token")
err = c.PasswordResetter.ValidateToken(uid, token)
if err == sql.ErrNoRows || err == c.ErrBadResetToken {
return c.LocalError("This reset token has expired.", w, r, user)

View File

@ -6,17 +6,18 @@ import (
"net/http"
"strconv"
"strings"
//"log"
c "github.com/Azareal/Gosora/common"
p "github.com/Azareal/Gosora/common/phrases"
)
func Convos(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
accountEditHead("convos", w, r, &user, header)
header.AddScript("convo.js")
header.AddSheet(header.Theme.Name + "/convo.css")
header.AddNotice("convo_dev")
func Convos(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
accountEditHead("convos", w, r, &user, h)
h.AddScript("convo.js")
h.AddSheet(h.Theme.Name + "/convo.css")
h.AddNotice("convo_dev")
ccount := c.Convos.GetUserCount(user.ID)
page, _ := strconv.Atoi(r.FormValue("page"))
offset, page, lastPage := c.PageOffset(ccount, page, c.Config.ItemsPerPage)
@ -25,13 +26,13 @@ func Convos(w http.ResponseWriter, r *http.Request, user c.User, header *c.Heade
convos, err := c.Convos.GetUserExtra(user.ID, offset)
//log.Printf("convos: %+v\n", convos)
if err == sql.ErrNoRows {
return c.NotFound(w, r, header)
return c.NotFound(w, r, h)
} else if err != nil {
return c.InternalError(err, w, r)
}
pi := c.Account{header, "dashboard", "convos", c.ConvoListPage{header, convos, c.Paginator{pageList, page, lastPage}}}
return renderTemplate("account", w, r, header, pi)
pi := c.Account{h, "dashboard", "convos", c.ConvoListPage{h, convos, c.Paginator{pageList, page, lastPage}}}
return renderTemplate("account", w, r, h, pi)
}
func Convo(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header, scid string) c.RouteError {
@ -99,12 +100,12 @@ func Convo(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header
return renderTemplate("account", w, r, header, pi)
}
func ConvosCreate(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
accountEditHead("create_convo", w, r, &user, header)
header.AddNotice("convo_dev")
func ConvosCreate(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
accountEditHead("create_convo", w, r, &user, h)
h.AddNotice("convo_dev")
recpName := ""
pi := c.Account{header, "dashboard", "create_convo", c.ConvoCreatePage{header, recpName}}
return renderTemplate("account", w, r, header, pi)
pi := c.Account{h, "dashboard", "create_convo", c.ConvoCreatePage{h, recpName}}
return renderTemplate("account", w, r, h, pi)
}
func ConvosCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
@ -112,7 +113,7 @@ func ConvosCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
if ferr != nil {
return ferr
}
if user.IsBanned {
if !user.Perms.UseConvos {
return c.NoPermissions(w, r, user)
}
@ -131,6 +132,10 @@ func ConvosCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
} else if err != nil {
return c.InternalError(err, w, r)
}
// TODO: Should we kick them out of existing conversations if they're moved into a group without permission or the permission is revoked from their group? We might want to give them a chance to delete their messages though to avoid privacy headaches here and it may only be temporarily to tackle a specific incident.
if !u.Perms.UseConvos {
return c.LocalError("One of the recipients doesn't have permission to use the conversations system", w, r, user)
}
rlist = append(rlist, u.ID)
}
@ -168,7 +173,7 @@ func ConvosCreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User
if ferr != nil {
return ferr
}
if user.IsBanned {
if !user.Perms.UseConvos {
return c.NoPermissions(w, r, user)
}
cid, err := strconv.Atoi(scid)
@ -263,6 +268,9 @@ func ConvosEditReplySubmit(w http.ResponseWriter, r *http.Request, user c.User,
if err != nil {
return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)
}
if !user.Perms.UseConvos {
return c.NoPermissions(w, r, user)
}
js := (r.PostFormValue("js") == "1")
post := &c.ConversationPost{ID: cpid}

View File

@ -38,15 +38,15 @@ func ForumList(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
var forumList []c.Forum
for _, fid := range canSee {
// Avoid data races by copying the struct into something we can freely mold without worrying about breaking something somewhere else
var forum = c.Forums.DirtyGet(fid).Copy()
if forum.ParentID == 0 && forum.Name != "" && forum.Active {
if forum.LastTopicID != 0 {
if forum.LastTopic.ID != 0 && forum.LastReplyer.ID != 0 {
forum.LastTopicTime = c.RelativeTime(forum.LastTopic.LastReplyAt)
f := c.Forums.DirtyGet(fid).Copy()
if f.ParentID == 0 && f.Name != "" && f.Active {
if f.LastTopicID != 0 {
if f.LastTopic.ID != 0 && f.LastReplyer.ID != 0 {
f.LastTopicTime = c.RelativeTime(f.LastTopic.LastReplyAt)
}
}
header.Hooks.Hook("forums_frow_assign", &forum)
forumList = append(forumList, forum)
header.Hooks.Hook("forums_frow_assign", &f)
forumList = append(forumList, f)
}
}

View File

@ -52,28 +52,28 @@ func StaticFile(w http.ResponseWriter, r *http.Request) {
// Other options instead of io.Copy: io.CopyN(), w.Write(), http.ServeContent()
}
func Overview(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
header.Title = phrases.GetTitlePhrase("overview")
header.Zone = "overview"
return renderTemplate("overview", w, r, header, c.Page{header, tList, nil})
func Overview(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
h.Title = phrases.GetTitlePhrase("overview")
h.Zone = "overview"
return renderTemplate("overview", w, r, h, c.Page{h, tList, nil})
}
func CustomPage(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header, name string) c.RouteError {
header.Zone = "custom_page"
func CustomPage(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header, name string) c.RouteError {
h.Zone = "custom_page"
name = c.SanitiseSingleLine(name)
page, err := c.Pages.GetByName(name)
if err == nil {
header.Title = page.Title
return renderTemplate("custom_page", w, r, header, c.CustomPagePage{header, page})
h.Title = page.Title
return renderTemplate("custom_page", w, r, h, c.CustomPagePage{h, page})
} else if err != sql.ErrNoRows {
return c.InternalError(err, w, r)
}
header.Title = phrases.GetTitlePhrase("page")
h.Title = phrases.GetTitlePhrase("page")
// TODO: Pass the page name to the pre-render hook?
err = renderTemplate3("page_"+name, "tmpl_page", w, r, header, c.Page{header, tList, nil})
err = renderTemplate3("page_"+name, "tmpl_page", w, r, h, c.Page{h, tList, nil})
if err == c.ErrBadDefaultTemplate {
return c.NotFound(w, r, header)
return c.NotFound(w, r, h)
} else if err != nil {
return c.InternalError(err, w, r)
}
@ -84,7 +84,7 @@ func CustomPage(w http.ResponseWriter, r *http.Request, user c.User, header *c.H
func ChangeTheme(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
//headerLite, _ := SimpleUserCheck(w, r, &user)
// TODO: Rename js to something else, just in case we rewrite the JS side in WebAssembly?
js := (r.PostFormValue("js") == "1")
js := r.PostFormValue("js") == "1"
newTheme := c.SanitiseSingleLine(r.PostFormValue("newTheme"))
theme, ok := c.Themes[newTheme]

View File

@ -80,7 +80,7 @@ func GroupsEdit(w http.ResponseWriter, r *http.Request, user c.User, sgid string
//log.Print("aaaaa monsters")
return c.NotFound(w, r, basePage.Header)
}
ferr = groupCheck(w,r,user,g,err)
ferr = groupCheck(w, r, user, g, err)
if ferr != nil {
return ferr
}
@ -122,7 +122,7 @@ func GroupsEditPromotions(w http.ResponseWriter, r *http.Request, user c.User, s
//log.Print("aaaaa monsters")
return c.NotFound(w, r, basePage.Header)
}
ferr = groupCheck(w,r,user,g,err)
ferr = groupCheck(w, r, user, g, err)
if ferr != nil {
return ferr
}
@ -343,6 +343,7 @@ func GroupsEditPerms(w http.ResponseWriter, r *http.Request, user c.User, sgid s
addGlobalPerm("ViewIPs", g.Perms.ViewIPs)
addGlobalPerm("UploadFiles", g.Perms.UploadFiles)
addGlobalPerm("UploadAvatars", g.Perms.UploadAvatars)
addGlobalPerm("UseConvos", g.Perms.UseConvos)
pi := c.PanelEditGroupPermsPage{basePage, g.ID, g.Name, localPerms, globalPerms}
return renderTemplate("panel_group_edit_perms", w, r, basePage.Header, pi)

View File

@ -7,7 +7,7 @@ import (
"strings"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/phrases"
p "github.com/Azareal/Gosora/common/phrases"
)
func Settings(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
@ -24,33 +24,34 @@ func Settings(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
if err != nil {
return c.InternalError(err, w, r)
}
settingPhrases := phrases.GetAllSettingPhrases()
settingPhrases := p.GetAllSettingPhrases()
var settingList []*c.PanelSetting
for _, settingPtr := range settings {
setting := settingPtr.Copy()
if setting.Type == "list" {
llist := settingPhrases[setting.Name+"_label"]
s := settingPtr.Copy()
if s.Type == "list" {
llist := settingPhrases[s.Name+"_label"]
labels := strings.Split(llist, ",")
conv, err := strconv.Atoi(setting.Content)
conv, err := strconv.Atoi(s.Content)
if err != nil {
return c.LocalError("The setting '"+setting.Name+"' can't be converted to an integer", w, r, user)
return c.LocalError("The setting '"+s.Name+"' can't be converted to an integer", w, r, user)
}
setting.Content = labels[conv-1]
} else if setting.Type == "bool" {
if setting.Content == "1" {
setting.Content = "Yes"
s.Content = labels[conv-1]
// TODO: Localise this
} else if s.Type == "bool" {
if s.Content == "1" {
s.Content = "Yes"
} else {
setting.Content = "No"
s.Content = "No"
}
} else if setting.Type == "html-attribute" {
setting.Type = "textarea"
} else if s.Type == "html-attribute" {
s.Type = "textarea"
}
settingList = append(settingList, &c.PanelSetting{setting, phrases.GetSettingPhrase(setting.Name)})
settingList = append(settingList, &c.PanelSetting{s, p.GetSettingPhrase(s.Name)})
}
pi := c.PanelPage{basePage, tList, settingList}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_settings",&pi})
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_settings", &pi})
}
func SettingEdit(w http.ResponseWriter, r *http.Request, user c.User, sname string) c.RouteError {
@ -71,7 +72,7 @@ func SettingEdit(w http.ResponseWriter, r *http.Request, user c.User, sname stri
var itemList []c.OptionLabel
if setting.Type == "list" {
llist := phrases.GetSettingPhrase(setting.Name + "_label")
llist := p.GetSettingPhrase(setting.Name + "_label")
conv, err := strconv.Atoi(setting.Content)
if err != nil {
return c.LocalError("The value of this setting couldn't be converted to an integer", w, r, user)
@ -88,9 +89,9 @@ func SettingEdit(w http.ResponseWriter, r *http.Request, user c.User, sname stri
setting.Type = "textarea"
}
pSetting := &c.PanelSetting{setting, phrases.GetSettingPhrase(setting.Name)}
pSetting := &c.PanelSetting{setting, p.GetSettingPhrase(setting.Name)}
pi := c.PanelSettingPage{basePage, itemList, pSetting}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_setting",&pi})
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_setting", &pi})
}
func SettingEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sname string) c.RouteError {

View File

@ -34,7 +34,7 @@ func Themes(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
}
pi := c.PanelThemesPage{basePage, pThemeList, vThemeList}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"panel_themes","","panel_themes",&pi})
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_themes", "", "panel_themes", &pi})
}
func ThemesSetDefault(w http.ResponseWriter, r *http.Request, user c.User, uname string) c.RouteError {
@ -74,7 +74,7 @@ func ThemesMenus(w http.ResponseWriter, r *http.Request, user c.User) c.RouteErr
var menuList []c.PanelMenuListItem
for mid, list := range c.Menus.GetAllMap() {
var name = ""
name := ""
if mid == 1 {
name = p.GetTmplPhrase("panel_themes_menus_main")
}
@ -85,7 +85,7 @@ func ThemesMenus(w http.ResponseWriter, r *http.Request, user c.User) c.RouteErr
})
}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_themes_menus", &c.PanelMenuListPage{basePage, menuList}})
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_themes_menus", &c.PanelMenuListPage{basePage, menuList}})
}
func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user c.User, smid string) c.RouteError {
@ -132,7 +132,7 @@ func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user c.User, smid s
menuList = append(menuList, item)
}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_themes_menus_items", &c.PanelMenuPage{basePage, mid, menuList}})
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_themes_menus_items", &c.PanelMenuPage{basePage, mid, menuList}})
}
func ThemesMenuItemEdit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError {
@ -157,53 +157,53 @@ func ThemesMenuItemEdit(w http.ResponseWriter, r *http.Request, user c.User, sit
return c.InternalError(err, w, r)
}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_themes_menus_item_edit", &c.PanelMenuItemPage{basePage, menuItem}})
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_themes_menus_item_edit", &c.PanelMenuItemPage{basePage, menuItem}})
}
func themesMenuItemSetters(r *http.Request, mItem c.MenuItem) c.MenuItem {
func themesMenuItemSetters(r *http.Request, i c.MenuItem) c.MenuItem {
getItem := func(name string) string {
return c.SanitiseSingleLine(r.PostFormValue("item-" + name))
}
mItem.Name = getItem("name")
mItem.HTMLID = getItem("htmlid")
mItem.CSSClass = getItem("cssclass")
mItem.Position = getItem("position")
if mItem.Position != "left" && mItem.Position != "right" {
mItem.Position = "left"
i.Name = getItem("name")
i.HTMLID = getItem("htmlid")
i.CSSClass = getItem("cssclass")
i.Position = getItem("position")
if i.Position != "left" && i.Position != "right" {
i.Position = "left"
}
mItem.Path = getItem("path")
mItem.Aria = getItem("aria")
mItem.Tooltip = getItem("tooltip")
mItem.TmplName = getItem("tmplname")
i.Path = getItem("path")
i.Aria = getItem("aria")
i.Tooltip = getItem("tooltip")
i.TmplName = getItem("tmplname")
switch getItem("permissions") {
case "everyone":
mItem.GuestOnly = false
mItem.MemberOnly = false
mItem.SuperModOnly = false
mItem.AdminOnly = false
i.GuestOnly = false
i.MemberOnly = false
i.SuperModOnly = false
i.AdminOnly = false
case "guest-only":
mItem.GuestOnly = true
mItem.MemberOnly = false
mItem.SuperModOnly = false
mItem.AdminOnly = false
i.GuestOnly = true
i.MemberOnly = false
i.SuperModOnly = false
i.AdminOnly = false
case "member-only":
mItem.GuestOnly = false
mItem.MemberOnly = true
mItem.SuperModOnly = false
mItem.AdminOnly = false
i.GuestOnly = false
i.MemberOnly = true
i.SuperModOnly = false
i.AdminOnly = false
case "supermod-only":
mItem.GuestOnly = false
mItem.MemberOnly = true
mItem.SuperModOnly = true
mItem.AdminOnly = false
i.GuestOnly = false
i.MemberOnly = true
i.SuperModOnly = true
i.AdminOnly = false
case "admin-only":
mItem.GuestOnly = false
mItem.MemberOnly = true
mItem.SuperModOnly = true
mItem.AdminOnly = true
i.GuestOnly = false
i.MemberOnly = true
i.SuperModOnly = true
i.AdminOnly = true
}
return mItem
return i
}
func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError {
@ -211,7 +211,7 @@ func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user c.Use
if ferr != nil {
return ferr
}
js := (r.PostFormValue("js") == "1")
js := r.PostFormValue("js") == "1"
if !user.Perms.ManageThemes {
return c.NoPermissionsJSQ(w, r, user, js)
}
@ -243,7 +243,7 @@ func ThemesMenuItemCreateSubmit(w http.ResponseWriter, r *http.Request, user c.U
return ferr
}
js := (r.PostFormValue("js") == "1")
js := r.PostFormValue("js") == "1"
if !user.Perms.ManageThemes {
return c.NoPermissionsJSQ(w, r, user, js)
}
@ -270,7 +270,7 @@ func ThemesMenuItemDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.U
if ferr != nil {
return ferr
}
js := (r.PostFormValue("js") == "1")
js := r.PostFormValue("js") == "1"
if !user.Perms.ManageThemes {
return c.NoPermissionsJSQ(w, r, user, js)
}
@ -299,7 +299,7 @@ func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user c.Us
if ferr != nil {
return ferr
}
js := (r.PostFormValue("js") == "1")
js := r.PostFormValue("js") == "1"
if !user.Perms.ManageThemes {
return c.NoPermissionsJSQ(w, r, user, js)
}
@ -341,14 +341,14 @@ func ThemesWidgets(w http.ResponseWriter, r *http.Request, user c.User) c.RouteE
}
basePage.Header.AddScript("widgets.js")
var docks = make(map[string][]c.WidgetEdit)
docks := make(map[string][]c.WidgetEdit)
for _, name := range c.GetDockList() {
if name == "leftOfNav" || name == "rightOfNav" {
continue
}
var widgets []c.WidgetEdit
for _, widget := range c.GetDock(name) {
var data = make(map[string]string)
data := make(map[string]string)
err := json.Unmarshal([]byte(widget.RawBody), &data)
if err != nil {
return c.InternalError(err, w, r)
@ -359,12 +359,12 @@ func ThemesWidgets(w http.ResponseWriter, r *http.Request, user c.User) c.RouteE
}
pi := c.PanelWidgetListPage{basePage, docks, c.WidgetEdit{&c.Widget{ID: 0, Type: "simple"}, make(map[string]string)}}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_themes_widgets", pi})
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_themes_widgets", pi})
}
func widgetsParseInputs(r *http.Request, widget *c.Widget) (*c.WidgetEdit, error) {
var data = make(map[string]string)
widget.Enabled = (r.FormValue("wenabled") == "1")
data := make(map[string]string)
widget.Enabled = r.FormValue("wenabled") == "1"
widget.Location = r.FormValue("wlocation")
if widget.Location == "" {
return nil, errors.New("You need to specify a location for this widget.")
@ -374,7 +374,7 @@ func widgetsParseInputs(r *http.Request, widget *c.Widget) (*c.WidgetEdit, error
return nil, errors.New("The widget dock you specified doesn't exist.")
}
var wtype = r.FormValue("wtype")
wtype := r.FormValue("wtype")
switch wtype {
case "simple", "about":
data["Name"] = r.FormValue("wname")
@ -402,7 +402,7 @@ func ThemesWidgetsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User
if ferr != nil {
return ferr
}
js := (r.PostFormValue("js") == "1")
js := r.PostFormValue("js") == "1"
if !user.Perms.ManageThemes {
return c.NoPermissionsJSQ(w, r, user, js)
}
@ -435,7 +435,7 @@ func ThemesWidgetsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User
// ThemesWidgetsCreateSubmit is an action which is triggered when someone sends a create request for a widget
func ThemesWidgetsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
//fmt.Println("in ThemesWidgetsCreateSubmit")
js := (r.PostFormValue("js") == "1")
js := r.PostFormValue("js") == "1"
_, ferr := c.SimplePanelUserCheck(w, r, &user)
if ferr != nil {
return ferr
@ -462,7 +462,7 @@ func ThemesWidgetsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.Us
if ferr != nil {
return ferr
}
js := (r.PostFormValue("js") == "1")
js := r.PostFormValue("js") == "1"
if !user.Perms.ManageThemes {
return c.NoPermissionsJSQ(w, r, user, js)
}

View File

@ -7,7 +7,7 @@ import (
"strconv"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/query_gen"
qgen "github.com/Azareal/Gosora/query_gen"
)
func PollVote(w http.ResponseWriter, r *http.Request, user c.User, sPollID string) c.RouteError {
@ -57,7 +57,6 @@ func PollVote(w http.ResponseWriter, r *http.Request, user c.User, sPollID strin
if err != nil {
return c.LocalError("Malformed input", w, r, user)
}
err = poll.CastVote(optionIndex, user.ID, user.LastIP)
if err != nil {
return c.InternalError(err, w, r)
@ -88,7 +87,7 @@ func PollResults(w http.ResponseWriter, r *http.Request, user c.User, sPollID st
}
defer rows.Close()
var optionList = ""
optionList := ""
for rows.Next() {
var votes int
err := rows.Scan(&votes)

View File

@ -19,16 +19,16 @@ func wsTopicList(topicList []*c.TopicsRow, lastPage int) *c.WsTopicList {
return &c.WsTopicList{wsTopicList, lastPage, 0}
}
func TopicList(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
skip, rerr := header.Hooks.VhookSkippable("route_topic_list_start", w, r, &user, header)
func TopicList(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
skip, rerr := h.Hooks.VhookSkippable("route_topic_list_start", w, r, &user, h)
if skip || rerr != nil {
return rerr
}
return TopicListCommon(w, r, user, header, "lastupdated", "")
return TopicListCommon(w, r, user, h, "lastupdated", "")
}
func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
return TopicListCommon(w, r, user, header, "mostviewed", "most-viewed")
func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
return TopicListCommon(w, r, user, h, "mostviewed", "most-viewed")
}
// TODO: Implement search
@ -85,7 +85,7 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, header
var cfids []int
if len(fids) > 0 {
var inSlice = func(haystack []int, needle int) bool {
inSlice := func(haystack []int, needle int) bool {
for _, item := range haystack {
if needle == item {
return true
@ -117,7 +117,7 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, header
if err != nil {
return c.InternalError(err, w, r)
}
var reqUserList = make(map[int]bool)
reqUserList := make(map[int]bool)
for _, topic := range tMap {
reqUserList[topic.CreatedBy] = true
reqUserList[topic.LastReplyBy] = true
@ -126,7 +126,7 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, header
//fmt.Printf("reqUserList %+v\n", reqUserList)
// Convert the user ID map to a slice, then bulk load the users
var idSlice = make([]int, len(reqUserList))
idSlice := make([]int, len(reqUserList))
var i int
for userID := range reqUserList {
idSlice[i] = userID

View File

@ -7,9 +7,9 @@ INSERT INTO [settings] ([name],[content],[type]) VALUES ('rapid_loading','1','bo
INSERT INTO [settings] ([name],[content],[type]) VALUES ('google_site_verify','','html-attribute');
INSERT INTO [themes] ([uname],[default]) VALUES ('cosora',1);
INSERT INTO [emails] ([email],[uid],[validated]) VALUES ('admin@localhost',1,1);
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[tag]) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[tag]) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms]) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[tag]) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[tag]) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms]) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_banned]) VALUES ('Banned','{"ViewTopic":true}','{}',1);
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms]) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[tag]) VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest');
@ -36,6 +36,6 @@ INSERT INTO [menu_items] ([mid],[htmlID],[cssClass],[position],[tmplName],[order
INSERT INTO [menu_items] ([mid],[name],[cssClass],[position],[path],[aria],[tooltip],[memberOnly],[order]) VALUES (1,'{lang.menu_account}','menu_account','left','/user/edit/','{lang.menu_account_aria}','{lang.menu_account_tooltip}',1,3);
INSERT INTO [menu_items] ([mid],[name],[cssClass],[position],[path],[aria],[tooltip],[memberOnly],[order]) VALUES (1,'{lang.menu_profile}','menu_profile','left','{me.Link}','{lang.menu_profile_aria}','{lang.menu_profile_tooltip}',1,4);
INSERT INTO [menu_items] ([mid],[name],[cssClass],[position],[path],[aria],[tooltip],[memberOnly],[staffOnly],[order]) VALUES (1,'{lang.menu_panel}','menu_panel menu_account','left','/panel/','{lang.menu_panel_aria}','{lang.menu_panel_tooltip}',1,1,5);
INSERT INTO [menu_items] ([mid],[name],[cssClass],[position],[path],[aria],[tooltip],[memberOnly],[order]) VALUES (1,'{lang.menu_logout}','menu_logout','left','/accounts/logout/?session={me.Session}','{lang.menu_logout_aria}','{lang.menu_logout_tooltip}',1,6);
INSERT INTO [menu_items] ([mid],[name],[cssClass],[position],[path],[aria],[tooltip],[memberOnly],[order]) VALUES (1,'{lang.menu_logout}','menu_logout','left','/accounts/logout/?s={me.Session}','{lang.menu_logout_aria}','{lang.menu_logout_tooltip}',1,6);
INSERT INTO [menu_items] ([mid],[name],[cssClass],[position],[path],[aria],[tooltip],[guestOnly],[order]) VALUES (1,'{lang.menu_register}','menu_register','left','/accounts/create/','{lang.menu_register_aria}','{lang.menu_register_tooltip}',1,7);
INSERT INTO [menu_items] ([mid],[name],[cssClass],[position],[path],[aria],[tooltip],[guestOnly],[order]) VALUES (1,'{lang.menu_login}','menu_login','left','/accounts/login/','{lang.menu_login_aria}','{lang.menu_login_tooltip}',1,8);

View File

@ -15,9 +15,9 @@ INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('rapid_loading','1','boo
INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('google_site_verify','','html-attribute');
INSERT INTO `themes`(`uname`,`default`) VALUES ('cosora',1);
INSERT INTO `emails`(`email`,`uid`,`validated`) VALUES ('admin@localhost',1,1);
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`tag`) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`tag`) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_banned`) VALUES ('Banned','{"ViewTopic":true}','{}',1);
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`tag`) VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest');
@ -44,6 +44,6 @@ INSERT INTO `menu_items`(`mid`,`htmlID`,`cssClass`,`position`,`tmplName`,`order`
INSERT INTO `menu_items`(`mid`,`name`,`cssClass`,`position`,`path`,`aria`,`tooltip`,`memberOnly`,`order`) VALUES (1,'{lang.menu_account}','menu_account','left','/user/edit/','{lang.menu_account_aria}','{lang.menu_account_tooltip}',1,3);
INSERT INTO `menu_items`(`mid`,`name`,`cssClass`,`position`,`path`,`aria`,`tooltip`,`memberOnly`,`order`) VALUES (1,'{lang.menu_profile}','menu_profile','left','{me.Link}','{lang.menu_profile_aria}','{lang.menu_profile_tooltip}',1,4);
INSERT INTO `menu_items`(`mid`,`name`,`cssClass`,`position`,`path`,`aria`,`tooltip`,`memberOnly`,`staffOnly`,`order`) VALUES (1,'{lang.menu_panel}','menu_panel menu_account','left','/panel/','{lang.menu_panel_aria}','{lang.menu_panel_tooltip}',1,1,5);
INSERT INTO `menu_items`(`mid`,`name`,`cssClass`,`position`,`path`,`aria`,`tooltip`,`memberOnly`,`order`) VALUES (1,'{lang.menu_logout}','menu_logout','left','/accounts/logout/?session={me.Session}','{lang.menu_logout_aria}','{lang.menu_logout_tooltip}',1,6);
INSERT INTO `menu_items`(`mid`,`name`,`cssClass`,`position`,`path`,`aria`,`tooltip`,`memberOnly`,`order`) VALUES (1,'{lang.menu_logout}','menu_logout','left','/accounts/logout/?s={me.Session}','{lang.menu_logout_aria}','{lang.menu_logout_tooltip}',1,6);
INSERT INTO `menu_items`(`mid`,`name`,`cssClass`,`position`,`path`,`aria`,`tooltip`,`guestOnly`,`order`) VALUES (1,'{lang.menu_register}','menu_register','left','/accounts/create/','{lang.menu_register_aria}','{lang.menu_register_tooltip}',1,7);
INSERT INTO `menu_items`(`mid`,`name`,`cssClass`,`position`,`path`,`aria`,`tooltip`,`guestOnly`,`order`) VALUES (1,'{lang.menu_login}','menu_login','left','/accounts/login/','{lang.menu_login_aria}','{lang.menu_login_tooltip}',1,8);

View File

@ -7,9 +7,9 @@ INSERT INTO "settings"("name","content","type") VALUES ('rapid_loading','1','boo
INSERT INTO "settings"("name","content","type") VALUES ('google_site_verify','','html-attribute');
INSERT INTO "themes"("uname","default") VALUES ('cosora',1);
INSERT INTO "emails"("email","uid","validated") VALUES ('admin@localhost',1,1);
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","tag") VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","tag") VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');
INSERT INTO "users_groups"("name","permissions","plugin_perms") VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}');
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","tag") VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","tag") VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');
INSERT INTO "users_groups"("name","permissions","plugin_perms") VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}');
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_banned") VALUES ('Banned','{"ViewTopic":true}','{}',1);
INSERT INTO "users_groups"("name","permissions","plugin_perms") VALUES ('Awaiting Activation','{"ViewTopic":true}','{}');
INSERT INTO "users_groups"("name","permissions","plugin_perms","tag") VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest');
@ -36,6 +36,6 @@ INSERT INTO "menu_items"("mid","htmlID","cssClass","position","tmplName","order"
INSERT INTO "menu_items"("mid","name","cssClass","position","path","aria","tooltip","memberOnly","order") VALUES (1,'{lang.menu_account}','menu_account','left','/user/edit/','{lang.menu_account_aria}','{lang.menu_account_tooltip}',1,3);
INSERT INTO "menu_items"("mid","name","cssClass","position","path","aria","tooltip","memberOnly","order") VALUES (1,'{lang.menu_profile}','menu_profile','left','{me.Link}','{lang.menu_profile_aria}','{lang.menu_profile_tooltip}',1,4);
INSERT INTO "menu_items"("mid","name","cssClass","position","path","aria","tooltip","memberOnly","staffOnly","order") VALUES (1,'{lang.menu_panel}','menu_panel menu_account','left','/panel/','{lang.menu_panel_aria}','{lang.menu_panel_tooltip}',1,1,5);
INSERT INTO "menu_items"("mid","name","cssClass","position","path","aria","tooltip","memberOnly","order") VALUES (1,'{lang.menu_logout}','menu_logout','left','/accounts/logout/?session={me.Session}','{lang.menu_logout_aria}','{lang.menu_logout_tooltip}',1,6);
INSERT INTO "menu_items"("mid","name","cssClass","position","path","aria","tooltip","memberOnly","order") VALUES (1,'{lang.menu_logout}','menu_logout','left','/accounts/logout/?s={me.Session}','{lang.menu_logout_aria}','{lang.menu_logout_tooltip}',1,6);
INSERT INTO "menu_items"("mid","name","cssClass","position","path","aria","tooltip","guestOnly","order") VALUES (1,'{lang.menu_register}','menu_register','left','/accounts/create/','{lang.menu_register_aria}','{lang.menu_register_tooltip}',1,7);
INSERT INTO "menu_items"("mid","name","cssClass","position","path","aria","tooltip","guestOnly","order") VALUES (1,'{lang.menu_login}','menu_login','left','/accounts/login/','{lang.menu_login_aria}','{lang.menu_login_tooltip}',1,8);

View File

@ -9,12 +9,12 @@
<div id="poweredBy">
<a id="poweredByName" href="https://github.com/Azareal/Gosora">{{lang "footer_powered_by"}}</a><span id="poweredByDash"> - </span><span id="poweredByMaker">{{lang "footer_made_with_love"}}</span>
</div>
{{/**{{if .CurrentUser.IsAdmin}}**/}}<div title="start to before tmpl" class="elapsed">{{.Header.Elapsed1}}</div><div title="start to footer" class="elapsed">{{elapsed .Header.StartedAt}}</div>{{/**{{end}}**/}}
{{if .CurrentUser.IsAdmin}}<div title="start to before tmpl" class="elapsed">{{.Header.Elapsed1}}</div><div title="start to footer" class="elapsed">{{elapsed .Header.StartedAt}}</div>{{end}}
<form action="/theme/" method="post">
<div id="themeSelector">
<select id="themeSelectorSelect" name="themeSelector" aria-label="{{lang "footer_theme_selector_aria"}}">{{range .Header.Themes}}
{{if not .HideFromThemes}}<option val="{{.Name}}"{{if eq $.Header.Theme.Name .Name}} selected{{end}}>{{.FriendlyName}}</option>{{end}}
{{end}}</select>
<select id="themeSelectorSelect" name="themeSelector" aria-label="{{lang "footer_theme_selector_aria"}}">{{range .Header.Themes}}{{if not .HideFromThemes}}
<option val="{{.Name}}"{{if eq $.Header.Theme.Name .Name}} selected{{end}}>{{.FriendlyName}}</option>
{{end}}{{end}}</select>
<noscript><input type="submit" /></noscript>
</div>
</form>

View File

@ -15,8 +15,7 @@ import (
// TODO: Name the tasks so we can figure out which one it was when something goes wrong? Or maybe toss it up WithStack down there?
func runTasks(tasks []func() error) {
for _, task := range tasks {
err := task()
if err != nil {
if err := task(); err != nil {
c.LogError(err)
}
}
@ -24,8 +23,7 @@ func runTasks(tasks []func() error) {
func startTick() (abort bool) {
isDBDown := atomic.LoadInt32(&c.IsDBDown)
err := db.Ping()
if err != nil {
if err := db.Ping(); err != nil {
// TODO: There's a bit of a race here, but it doesn't matter if this error appears multiple times in the logs as it's capped at three times, we just want to cut it down 99% of the time
if isDBDown == 0 {
db.SetConnMaxLifetime(time.Second) // Drop all the connections and start over
@ -45,8 +43,7 @@ func startTick() (abort bool) {
}
func runHook(name string) {
err := c.RunTaskHook(name)
if err != nil {
if err := c.RunTaskHook(name); err != nil {
c.LogError(err, "Failed at task '"+name+"'")
}
}
@ -88,16 +85,14 @@ func tickLoop(thumbChan chan bool) {
runTasks(c.ScheduledSecondTasks)
// TODO: Stop hard-coding this
err := c.HandleExpiredScheduledGroups()
if err != nil {
if err := c.HandleExpiredScheduledGroups(); err != nil {
c.LogError(err)
}
// TODO: Handle delayed moderation tasks
// Sync with the database, if there are any changes
err = c.HandleServerSync()
if err != nil {
if err = c.HandleServerSync(); err != nil {
c.LogError(err)
}
@ -164,35 +159,30 @@ func dailies() {
}
if c.Config.LogPruneCutoff > -1 {
_, err := qgen.NewAcc().Delete("login_logs").DateOlderThan("doneAt",c.Config.LogPruneCutoff,"day").Run()
f := func(tbl string) {
_, err := qgen.NewAcc().Delete(tbl).DateOlderThan("doneAt",c.Config.LogPruneCutoff,"day").Run()
if err != nil {
c.LogError(err)
}
_, err = qgen.NewAcc().Delete("registration_logs").DateOlderThan("doneAt",c.Config.LogPruneCutoff,"day").Run()
if err != nil {
c.LogError(err)
}
f("login_logs")
f("registration_logs")
}
if c.Config.PostIPCutoff > -1 {
// TODO: Use unixtime to remove this MySQLesque logic?
_, err := qgen.NewAcc().Update("topics").Set("ipaddress = '0'").DateOlderThan("createdAt",c.Config.PostIPCutoff,"day").Where("ipaddress != '0'").Exec()
f := func(tbl string) {
_, err := qgen.NewAcc().Update(tbl).Set("ipaddress = '0'").DateOlderThan("createdAt",c.Config.PostIPCutoff,"day").Where("ipaddress != '0'").Exec()
if err != nil {
c.LogError(err)
}
_, err = qgen.NewAcc().Update("replies").Set("ipaddress = '0'").DateOlderThan("createdAt",c.Config.PostIPCutoff,"day").Where("ipaddress != '0'").Exec()
if err != nil {
c.LogError(err)
}
f("topics")
f("replies")
f("users_replies")
// TODO: Find some way of purging the ip data in polls_votes without breaking any anti-cheat measures which might be running... maybe hash it instead?
_, err = qgen.NewAcc().Update("users_replies").Set("ipaddress = '0'").DateOlderThan("createdAt",c.Config.PostIPCutoff,"day").Where("ipaddress != '0'").Exec()
if err != nil {
c.LogError(err)
}
// TODO: lastActiveAt isn't currently set, so we can't rely on this to purge last_ips of users who haven't been on in a while
/*_, err = qgen.NewAcc().Update("users").Set("last_ip = '0'").DateOlderThan("lastActiveAt",c.Config.PostIPCutoff,"day").Where("last_ip != '0'").Exec()
if err != nil {