From 6bae378db0e4c76ce017c5a590eaea7f3604dc4e Mon Sep 17 00:00:00 2001 From: Azareal Date: Sat, 11 Nov 2017 23:34:27 +0000 Subject: [PATCH] Moved the modlog and admin log logic to their own file. Refactored the code to use the new builder syntax. Fixed the DbInit logic. Made sure the prepared statements are cleaned up. Added the AdminOnly middleware and added it to the routes. Added the Query method to the selectBuilder. --- common/audit_logs.go | 37 +++++++++++ common/common.go | 14 ++-- common/extend.go | 33 +++++++--- common/forum_perms_store.go | 15 ++--- common/permissions.go | 1 + common/routes_common.go | 8 +++ common/setting.go | 32 +++++++--- common/tasks.go | 27 +++++--- common/themes.go | 21 ++++-- common/user_store.go | 30 ++------- common/utils.go | 22 ------- common/widgets.go | 36 ++++++++--- common/word_filters.go | 27 ++++++-- database.go | 1 + gen_router.go | 108 +++++++++++++++++++++++++++++++ general_test.go | 1 + panel_routes.go | 120 ++++------------------------------- query_gen/lib/accumulator.go | 8 +++ router_gen/routes.go | 36 +++++------ routes.go | 2 + 20 files changed, 338 insertions(+), 241 deletions(-) create mode 100644 common/audit_logs.go diff --git a/common/audit_logs.go b/common/audit_logs.go new file mode 100644 index 00000000..d74d6739 --- /dev/null +++ b/common/audit_logs.go @@ -0,0 +1,37 @@ +package common + +import ( + "database/sql" + + "../query_gen/lib" +) + +type LogStmts struct { + addModLogEntry *sql.Stmt + addAdminLogEntry *sql.Stmt +} + +var logStmts LogStmts + +func init() { + DbInits.Add(func() error { + acc := qgen.Builder.Accumulator() + logStmts = LogStmts{ + addModLogEntry: acc.Insert("moderation_logs").Columns("action, elementID, elementType, ipaddress, actorID, doneAt").Fields("?,?,?,?,?,UTC_TIMESTAMP()").Prepare(), + addAdminLogEntry: acc.Insert("administration_logs").Columns("action, elementID, elementType, ipaddress, actorID, doneAt").Fields("?,?,?,?,?,UTC_TIMESTAMP()").Prepare(), + } + return acc.FirstError() + }) +} + +// TODO: Make a store for this? +func AddModLog(action string, elementID int, elementType string, ipaddress string, actorID int) (err error) { + _, err = logStmts.addModLogEntry.Exec(action, elementID, elementType, ipaddress, actorID) + return err +} + +// TODO: Make a store for this? +func AddAdminLog(action string, elementID string, elementType int, ipaddress string, actorID int) (err error) { + _, err = logStmts.addAdminLogEntry.Exec(action, elementID, elementType, ipaddress, actorID) + return err +} diff --git a/common/common.go b/common/common.go index 288796b1..1e98d43f 100644 --- a/common/common.go +++ b/common/common.go @@ -1,6 +1,8 @@ package common -import "database/sql" +import ( + "database/sql" +) // nolint I don't want to write comments for each of these o.o const Hour int = 60 * 60 @@ -60,11 +62,11 @@ func (slice StringList) Contains(needle string) bool { return false } -type DBInits []func() error +type dbInits []func() error -var DbInits DBInits +var DbInits dbInits -func (inits DBInits) Run() error { +func (inits dbInits) Run() error { for _, init := range inits { err := init() if err != nil { @@ -74,6 +76,6 @@ func (inits DBInits) Run() error { return nil } -func (inits DBInits) Add(init ...func() error) { - inits = append(inits, init...) +func (inits dbInits) Add(init ...func() error) { + DbInits = dbInits(append(DbInits, init...)) } diff --git a/common/extend.go b/common/extend.go index c6a06f94..288f2982 100644 --- a/common/extend.go +++ b/common/extend.go @@ -7,6 +7,7 @@ package common import ( + "database/sql" "log" "net/http" @@ -137,6 +138,22 @@ type Plugin struct { Data interface{} // Usually used for hosting the VMs / reusable elements of non-native plugins } +type ExtendStmts struct { + getPlugins *sql.Stmt +} + +var extendStmts ExtendStmts + +func init() { + DbInits.Add(func() error { + acc := qgen.Builder.Accumulator() + extendStmts = ExtendStmts{ + getPlugins: acc.Select("plugins").Columns("uname, active, installed").Prepare(), + } + return acc.FirstError() + }) +} + func InitExtend() (err error) { err = InitPluginLangs() if err != nil { @@ -147,11 +164,7 @@ func InitExtend() (err error) { // Load polls the database to see which plugins have been activated and which have been installed func (plugins PluginList) Load() error { - getPlugins, err := qgen.Builder.SimpleSelect("plugins", "uname, active, installed", "", "", "") - if err != nil { - return err - } - rows, err := getPlugins.Query() + rows, err := extendStmts.getPlugins.Query() if err != nil { return err } @@ -283,24 +296,24 @@ func (plugin *Plugin) RemoveHook(name string, handler interface{}) { delete(plugin.Hooks, name) } -var pluginsInited = false +var PluginsInited = false func InitPlugins() { for name, body := range Plugins { - log.Printf("Added plugin %s", name) + log.Printf("Added plugin '%s'", name) if body.Active { - log.Printf("Initialised plugin %s", name) + log.Printf("Initialised plugin '%s'", name) if Plugins[name].Init != nil { err := Plugins[name].Init() if err != nil { log.Print(err) } } else { - log.Printf("Plugin %s doesn't have an initialiser.", name) + log.Printf("Plugin '%s' doesn't have an initialiser.", name) } } } - pluginsInited = true + PluginsInited = true } // ? - Are the following functions racey? diff --git a/common/forum_perms_store.go b/common/forum_perms_store.go index fa954fad..262e2764 100644 --- a/common/forum_perms_store.go +++ b/common/forum_perms_store.go @@ -25,18 +25,11 @@ type MemoryForumPermsStore struct { } func NewMemoryForumPermsStore() (*MemoryForumPermsStore, error) { - getPermsStmt, err := qgen.Builder.SimpleSelect("forums_permissions", "gid, fid, permissions", "", "gid ASC, fid ASC", "") - if err != nil { - return nil, err - } - getPermsByForumStmt, err := qgen.Builder.SimpleSelect("forums_permissions", "gid, permissions", "fid = ?", "gid ASC", "") - if err != nil { - return nil, err - } + acc := qgen.Builder.Accumulator() return &MemoryForumPermsStore{ - get: getPermsStmt, - getByForum: getPermsByForumStmt, - }, nil + get: acc.Select("forums_permissions").Columns("gid, fid, permissions").Orderby("gid ASC, fid ASC").Prepare(), + getByForum: acc.Select("forums_permissions").Columns("gid, permissions").Where("fid = ?").Orderby("gid ASC").Prepare(), + }, acc.FirstError() } func (fps *MemoryForumPermsStore) Init() error { diff --git a/common/permissions.go b/common/permissions.go index d2ca6d59..6b954577 100644 --- a/common/permissions.go +++ b/common/permissions.go @@ -483,6 +483,7 @@ func RebuildGroupPermissions(gid int) error { if err != nil { return err } + defer getGroupPerms.Close() err = getGroupPerms.QueryRow(gid).Scan(&permstr) if err != nil { diff --git a/common/routes_common.go b/common/routes_common.go index 3656fa30..470d2912 100644 --- a/common/routes_common.go +++ b/common/routes_common.go @@ -294,6 +294,14 @@ func preRoute(w http.ResponseWriter, r *http.Request) (User, bool) { return *usercpy, true } +// AdminOnly makes sure that only admins can access certain panel routes +func AdminOnly(w http.ResponseWriter, r *http.Request, user User) RouteError { + if !user.IsAdmin { + return NoPermissions(w, r, user) + } + return nil +} + // SuperModeOnly makes sure that only super mods or higher can access the panel routes func SuperModOnly(w http.ResponseWriter, r *http.Request, user User) RouteError { if !user.IsSuperMod { diff --git a/common/setting.go b/common/setting.go index 4dcce5f9..a784de97 100644 --- a/common/setting.go +++ b/common/setting.go @@ -1,9 +1,13 @@ package common -import "strconv" -import "strings" -import "sync/atomic" -import "../query_gen/lib" +import ( + "database/sql" + "strconv" + "strings" + "sync/atomic" + + "../query_gen/lib" +) // SettingMap is a map type specifically for holding the various settings admins set to toggle features on and off or to otherwise alter Gosora's behaviour from the Control Panel type SettingMap map[string]interface{} @@ -23,17 +27,25 @@ type Setting struct { Constraint string } +type SettingStmts struct { + getFull *sql.Stmt +} + +var settingStmts SettingStmts + func init() { SettingBox.Store(SettingMap(make(map[string]interface{}))) + DbInits.Add(func() error { + acc := qgen.Builder.Accumulator() + settingStmts = SettingStmts{ + getFull: acc.Select("settings").Columns("name, content, type, constraints").Prepare(), + } + return acc.FirstError() + }) } func LoadSettings() error { - // TODO: Stop doing this inline - getFullSettings, err := qgen.Builder.SimpleSelect("settings", "name, content, type, constraints", "", "", "") - if err != nil { - return err - } - rows, err := getFullSettings.Query() + rows, err := settingStmts.getFull.Query() if err != nil { return err } diff --git a/common/tasks.go b/common/tasks.go index c5fb7d42..b1024cef 100644 --- a/common/tasks.go +++ b/common/tasks.go @@ -7,24 +7,35 @@ package common import ( + "database/sql" "log" "time" "../query_gen/lib" ) +type TaskStmts struct { + getExpiredScheduledGroups *sql.Stmt + getSync *sql.Stmt +} + +var taskStmts TaskStmts var lastSync time.Time func init() { lastSync = time.Now() + DbInits.Add(func() error { + acc := qgen.Builder.Accumulator() + taskStmts = TaskStmts{ + getExpiredScheduledGroups: acc.SimpleSelect("users_groups_scheduler", "uid", "UTC_TIMESTAMP() > revert_at AND temporary = 1", "", ""), + getSync: acc.SimpleSelect("sync", "last_update", "", "", ""), + } + return acc.FirstError() + }) } func HandleExpiredScheduledGroups() error { - getExpiredScheduledGroups, err := qgen.Builder.SimpleSelect("users_groups_scheduler", "uid", "UTC_TIMESTAMP() > revert_at AND temporary = 1", "", "") - if err != nil { - return err - } - rows, err := getExpiredScheduledGroups.Query() + rows, err := taskStmts.getExpiredScheduledGroups.Query() if err != nil { return err } @@ -50,11 +61,7 @@ func HandleExpiredScheduledGroups() error { func HandleServerSync() error { var lastUpdate time.Time - getSync, err := qgen.Builder.SimpleSelect("sync", "last_update", "", "", "") - if err != nil { - return err - } - err = getSync.QueryRow().Scan(&lastUpdate) + err := taskStmts.getSync.QueryRow().Scan(&lastUpdate) if err != nil { return err } diff --git a/common/themes.go b/common/themes.go index 41cfd0f1..87a01b99 100644 --- a/common/themes.go +++ b/common/themes.go @@ -4,6 +4,7 @@ package common import ( //"fmt" "bytes" + "database/sql" "encoding/json" "errors" "io/ioutil" @@ -74,20 +75,28 @@ type ThemeResource struct { Location string } +type ThemeStmts struct { + getThemes *sql.Stmt +} + +var themeStmts ThemeStmts + func init() { DefaultThemeBox.Store(fallbackTheme) + DbInits.Add(func() error { + acc := qgen.Builder.Accumulator() + themeStmts = ThemeStmts{ + getThemes: acc.Select("themes").Columns("uname, default").Prepare(), + } + return acc.FirstError() + }) } // TODO: Make the initThemes and LoadThemes functions less confusing // ? - Delete themes which no longer exist in the themes folder from the database? func (themes ThemeList) LoadActiveStatus() error { - getThemes, err := qgen.Builder.SimpleSelect("themes", "uname, default", "", "", "") - if err != nil { - return err - } - ChangeDefaultThemeMutex.Lock() - rows, err := getThemes.Query() + rows, err := themeStmts.getThemes.Query() if err != nil { return err } diff --git a/common/user_store.go b/common/user_store.go index 41f16472..a67c084d 100644 --- a/common/user_store.go +++ b/common/user_store.go @@ -170,12 +170,8 @@ func (mus *MemoryUserStore) BulkGetMap(ids []int) (list map[int]*User, err error } qlist = qlist[0 : len(qlist)-1] - stmt, err := qgen.Builder.SimpleSelect("users", "uid, name, group, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, last_ip, temp_group", "uid IN("+qlist+")", "", "") - if err != nil { - return nil, err - } - - rows, err := stmt.Query(uidList...) + acc := qgen.Builder.Accumulator() + rows, err := acc.Select("users").Columns("uid, name, group, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, last_ip, temp_group").Where("uid IN(" + qlist + ")").Query(uidList...) if err != nil { return nil, err } @@ -187,13 +183,8 @@ func (mus *MemoryUserStore) BulkGetMap(ids []int) (list map[int]*User, err error return nil, err } - // Initialise the user user.Init() - - // Add it to the cache... - _ = mus.CacheSet(user) - - // Add it to the list to be returned + mus.CacheSet(user) list[user.ID] = user } @@ -219,10 +210,10 @@ func (mus *MemoryUserStore) BulkGetMap(ids []int) (list map[int]*User, err error } sidList = sidList[0 : len(sidList)-1] - return list, errors.New("Unable to find the users with the following IDs: " + sidList) + err = errors.New("Unable to find the users with the following IDs: " + sidList) } - return list, nil + return list, err } func (mus *MemoryUserStore) BypassGet(id int) (*User, error) { @@ -420,12 +411,8 @@ func (mus *SQLUserStore) BulkGetMap(ids []int) (list map[int]*User, err error) { } qlist = qlist[0 : len(qlist)-1] - stmt, err := qgen.Builder.SimpleSelect("users", "uid, name, group, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, last_ip, temp_group", "uid IN("+qlist+")", "", "") - if err != nil { - return nil, err - } - - rows, err := stmt.Query(uidList...) + acc := qgen.Builder.Accumulator() + rows, err := acc.Select("users").Columns("uid, name, group, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, last_ip, temp_group").Where("uid IN(" + qlist + ")").Query(uidList...) if err != nil { return nil, err } @@ -438,10 +425,7 @@ func (mus *SQLUserStore) BulkGetMap(ids []int) (list map[int]*User, err error) { return nil, err } - // Initialise the user user.Init() - - // Add it to the list to be returned list[user.ID] = user } diff --git a/common/utils.go b/common/utils.go index 71a3bc6c..d375b0be 100644 --- a/common/utils.go +++ b/common/utils.go @@ -17,8 +17,6 @@ import ( "strings" "time" "unicode" - - "../query_gen/lib" ) // Version stores a Gosora version @@ -374,23 +372,3 @@ func BuildSlug(slug string, id int) string { } return slug + "." + strconv.Itoa(id) } - -// TODO: Make a store for this? -func AddModLog(action string, elementID int, elementType string, ipaddress string, actorID int) (err error) { - addModLogEntry, err := qgen.Builder.SimpleInsert("moderation_logs", "action, elementID, elementType, ipaddress, actorID, doneAt", "?,?,?,?,?,UTC_TIMESTAMP()") - if err != nil { - return err - } - _, err = addModLogEntry.Exec(action, elementID, elementType, ipaddress, actorID) - return err -} - -// TODO: Make a store for this? -func AddAdminLog(action string, elementID string, elementType int, ipaddress string, actorID int) (err error) { - addAdminLogEntry, err := qgen.Builder.SimpleInsert("administration_logs", "action, elementID, elementType, ipaddress, actorID, doneAt", "?,?,?,?,?,UTC_TIMESTAMP()") - if err != nil { - return err - } - _, err = addAdminLogEntry.Exec(action, elementID, elementType, ipaddress, actorID) - return err -} diff --git a/common/widgets.go b/common/widgets.go index 8c6be918..a4711e72 100644 --- a/common/widgets.go +++ b/common/widgets.go @@ -1,11 +1,15 @@ /* Copyright Azareal 2017 - 2018 */ package common -import "log" -import "bytes" -import "sync" -import "encoding/json" -import "../query_gen/lib" +import ( + "bytes" + "database/sql" + "encoding/json" + "log" + "sync" + + "../query_gen/lib" +) var Docks WidgetDocks var widgetUpdateMutex sync.RWMutex @@ -39,13 +43,25 @@ type NameTextPair struct { Text string } +type WidgetStmts struct { + getWidgets *sql.Stmt +} + +var widgetStmts WidgetStmts + +func init() { + DbInits.Add(func() error { + acc := qgen.Builder.Accumulator() + widgetStmts = WidgetStmts{ + getWidgets: acc.Select("widgets").Columns("position, side, type, active, location, data").Orderby("position ASC").Prepare(), + } + return acc.FirstError() + }) +} + // TODO: Make a store for this? func InitWidgets() error { - getWidgets, err := qgen.Builder.SimpleSelect("widgets", "position, side, type, active, location, data", "", "position ASC", "") - if err != nil { - return err - } - rows, err := getWidgets.Query() + rows, err := widgetStmts.getWidgets.Query() if err != nil { return err } diff --git a/common/word_filters.go b/common/word_filters.go index d5512c03..9915809e 100644 --- a/common/word_filters.go +++ b/common/word_filters.go @@ -1,7 +1,11 @@ package common -import "sync/atomic" -import "../query_gen/lib" +import ( + "database/sql" + "sync/atomic" + + "../query_gen/lib" +) type WordFilter struct { ID int @@ -12,16 +16,25 @@ type WordFilterMap map[int]WordFilter var WordFilterBox atomic.Value // An atomic value holding a WordFilterBox +type FilterStmts struct { + getWordFilters *sql.Stmt +} + +var filterStmts FilterStmts + func init() { WordFilterBox.Store(WordFilterMap(make(map[int]WordFilter))) + DbInits.Add(func() error { + acc := qgen.Builder.Accumulator() + filterStmts = FilterStmts{ + getWordFilters: acc.Select("word_filters").Columns("wfid, find, replacement").Prepare(), + } + return acc.FirstError() + }) } func LoadWordFilters() error { - getWordFilters, err := qgen.Builder.SimpleSelect("word_filters", "wfid, find, replacement", "", "", "") - if err != nil { - return err - } - rows, err := getWordFilters.Query() + rows, err := filterStmts.getWordFilters.Query() if err != nil { return err } diff --git a/database.go b/database.go index e4bcd97e..0f37fc30 100644 --- a/database.go +++ b/database.go @@ -28,6 +28,7 @@ func InitDatabase() (err error) { } globs = &Globs{stmts} + log.Print("Running the db handlers.") err = common.DbInits.Run() if err != nil { return err diff --git a/gen_router.go b/gen_router.go index 72f62d29..6d82ccca 100644 --- a/gen_router.go +++ b/gen_router.go @@ -192,50 +192,134 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { case "/panel/forums/": err = routePanelForums(w,req,user) case "/panel/forums/create/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelForumsCreateSubmit(w,req,user) case "/panel/forums/delete/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelForumsDelete(w,req,user,extra_data) case "/panel/forums/delete/submit/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelForumsDeleteSubmit(w,req,user,extra_data) case "/panel/forums/edit/": err = routePanelForumsEdit(w,req,user,extra_data) case "/panel/forums/edit/submit/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelForumsEditSubmit(w,req,user,extra_data) case "/panel/forums/edit/perms/submit/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelForumsEditPermsSubmit(w,req,user,extra_data) case "/panel/settings/": err = routePanelSettings(w,req,user) case "/panel/settings/edit/": err = routePanelSetting(w,req,user,extra_data) case "/panel/settings/edit/submit/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelSettingEdit(w,req,user,extra_data) case "/panel/settings/word-filters/": err = routePanelWordFilters(w,req,user) case "/panel/settings/word-filters/create/": + err = common.ParseForm(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelWordFiltersCreate(w,req,user) case "/panel/settings/word-filters/edit/": err = routePanelWordFiltersEdit(w,req,user,extra_data) case "/panel/settings/word-filters/edit/submit/": + err = common.ParseForm(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelWordFiltersEditSubmit(w,req,user,extra_data) case "/panel/settings/word-filters/delete/submit/": + err = common.ParseForm(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelWordFiltersDeleteSubmit(w,req,user,extra_data) case "/panel/themes/": err = routePanelThemes(w,req,user) case "/panel/themes/default/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelThemesSetDefault(w,req,user,extra_data) case "/panel/plugins/": err = routePanelPlugins(w,req,user) case "/panel/plugins/activate/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelPluginsActivate(w,req,user,extra_data) case "/panel/plugins/deactivate/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelPluginsDeactivate(w,req,user,extra_data) case "/panel/plugins/install/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelPluginsInstall(w,req,user,extra_data) case "/panel/users/": err = routePanelUsers(w,req,user) case "/panel/users/edit/": err = routePanelUsersEdit(w,req,user,extra_data) case "/panel/users/edit/submit/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelUsersEditSubmit(w,req,user,extra_data) case "/panel/groups/": err = routePanelGroups(w,req,user) @@ -244,16 +328,40 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { case "/panel/groups/edit/perms/": err = routePanelGroupsEditPerms(w,req,user,extra_data) case "/panel/groups/edit/submit/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelGroupsEditSubmit(w,req,user,extra_data) case "/panel/groups/edit/perms/submit/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelGroupsEditPermsSubmit(w,req,user,extra_data) case "/panel/groups/create/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelGroupsCreateSubmit(w,req,user) case "/panel/backups/": err = routePanelBackups(w,req,user,extra_data) case "/panel/logs/mod/": err = routePanelLogsMod(w,req,user) case "/panel/debug/": + err = common.AdminOnly(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + err = routePanelDebug(w,req,user) default: err = routePanel(w,req,user) diff --git a/general_test.go b/general_test.go index e30ab5bb..4824d21d 100644 --- a/general_test.go +++ b/general_test.go @@ -553,6 +553,7 @@ func BenchmarkQueryPreparedTopicParallel(b *testing.B) { if err != nil { b.Fatal(err) } + defer getTopicUser.Close() for pb.Next() { err := getTopicUser.QueryRow(1).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.IsClosed, &tu.Sticky, &tu.ParentID, &tu.IPAddress, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level) diff --git a/panel_routes.go b/panel_routes.go index d3910280..7d910ca0 100644 --- a/panel_routes.go +++ b/panel_routes.go @@ -229,21 +229,13 @@ func routePanelForumsCreateSubmit(w http.ResponseWriter, r *http.Request, user c return common.NoPermissions(w, r, user) } - err := r.ParseForm() - if err != nil { - return common.LocalError("Bad Form", w, r, user) - } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } - fname := r.PostFormValue("forum-name") fdesc := r.PostFormValue("forum-desc") fpreset := common.StripInvalidPreset(r.PostFormValue("forum-preset")) factive := r.PostFormValue("forum-name") active := (factive == "on" || factive == "1") - _, err = common.Fstore.Create(fname, fdesc, active, fpreset) + _, err := common.Fstore.Create(fname, fdesc, active, fpreset) if err != nil { return common.InternalError(err, w, r) } @@ -261,9 +253,6 @@ func routePanelForumsDelete(w http.ResponseWriter, r *http.Request, user common. if !user.Perms.ManageForums { return common.NoPermissions(w, r, user) } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } fid, err := strconv.Atoi(sfid) if err != nil { @@ -301,9 +290,6 @@ func routePanelForumsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c if !user.Perms.ManageForums { return common.NoPermissions(w, r, user) } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } fid, err := strconv.Atoi(sfid) if err != nil { @@ -380,14 +366,6 @@ func routePanelForumsEditSubmit(w http.ResponseWriter, r *http.Request, user com if !user.Perms.ManageForums { return common.NoPermissions(w, r, user) } - - err := r.ParseForm() - if err != nil { - return common.LocalError("Bad Form", w, r, user) - } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } isJs := (r.PostFormValue("js") == "1") fid, err := strconv.Atoi(sfid) @@ -435,14 +413,6 @@ func routePanelForumsEditPermsSubmit(w http.ResponseWriter, r *http.Request, use if !user.Perms.ManageForums { return common.NoPermissions(w, r, user) } - - err := r.ParseForm() - if err != nil { - return common.LocalError("Bad Form", w, r, user) - } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } isJs := (r.PostFormValue("js") == "1") fid, err := strconv.Atoi(sfid) @@ -620,18 +590,10 @@ func routePanelSettingEdit(w http.ResponseWriter, r *http.Request, user common.U return common.NoPermissions(w, r, user) } - err := r.ParseForm() - if err != nil { - return common.LocalError("Bad Form", w, r, user) - } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } - var stype, sconstraints string scontent := r.PostFormValue("setting-value") - err = stmts.getFullSetting.QueryRow(sname).Scan(&sname, &stype, &sconstraints) + err := stmts.getFullSetting.QueryRow(sname).Scan(&sname, &stype, &sconstraints) if err == ErrNoRows { return common.LocalError("The setting you want to edit doesn't exist.", w, r, user) } else if err != nil { @@ -665,7 +627,7 @@ func routePanelSettingEdit(w http.ResponseWriter, r *http.Request, user common.U func routePanelWordFilters(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { headerVars, stats, ferr := common.PanelUserCheck(w, r, &user) if ferr != nil { - return nil + return ferr } if !user.Perms.EditSettings { return common.NoPermissions(w, r, user) @@ -693,11 +655,6 @@ func routePanelWordFiltersCreate(w http.ResponseWriter, r *http.Request, user co if !user.Perms.EditSettings { return common.NoPermissions(w, r, user) } - - err := r.ParseForm() - if err != nil { - return common.PreError("Bad Form", w, r) - } isJs := (r.PostFormValue("js") == "1") find := strings.TrimSpace(r.PostFormValue("find")) @@ -755,11 +712,6 @@ func routePanelWordFiltersEditSubmit(w http.ResponseWriter, r *http.Request, use if ferr != nil { return ferr } - - err := r.ParseForm() - if err != nil { - return common.PreError("Bad Form", w, r) - } // TODO: Either call it isJs or js rather than flip-flopping back and forth across the routes x.x isJs := (r.PostFormValue("isJs") == "1") if !user.Perms.EditSettings { @@ -798,10 +750,6 @@ func routePanelWordFiltersDeleteSubmit(w http.ResponseWriter, r *http.Request, u return ferr } - err := r.ParseForm() - if err != nil { - return common.PreError("Bad Form", w, r) - } isJs := (r.PostFormValue("isJs") == "1") if !user.Perms.EditSettings { return common.NoPermissionsJSQ(w, r, user, isJs) @@ -860,16 +808,11 @@ func routePanelPluginsActivate(w http.ResponseWriter, r *http.Request, user comm if !user.Perms.ManagePlugins { return common.NoPermissions(w, r, user) } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } - //log.Print("uname","'"+uname+"'") plugin, ok := common.Plugins[uname] if !ok { return common.LocalError("The plugin isn't registered in the system", w, r, user) } - if plugin.Installable && !plugin.Installed { return common.LocalError("You can't activate this plugin without installing it first", w, r, user) } @@ -888,26 +831,19 @@ func routePanelPluginsActivate(w http.ResponseWriter, r *http.Request, user comm } } - //log.Print("err", err) - //log.Print("active", active) if hasPlugin { if active { return common.LocalError("The plugin is already active", w, r, user) } - //log.Print("updatePlugin") _, err = stmts.updatePlugin.Exec(1, uname) - if err != nil { - return common.InternalError(err, w, r) - } } else { - //log.Print("addPlugin") - _, err := stmts.addPlugin.Exec(uname, 1, 0) - if err != nil { - return common.InternalError(err, w, r) - } + _, err = stmts.addPlugin.Exec(uname, 1, 0) + } + if err != nil { + return common.InternalError(err, w, r) } - log.Print("Activating plugin '" + plugin.Name + "'") + log.Printf("Activating plugin '%s'", plugin.Name) plugin.Active = true common.Plugins[uname] = plugin err = common.Plugins[uname].Init() @@ -927,9 +863,6 @@ func routePanelPluginsDeactivate(w http.ResponseWriter, r *http.Request, user co if !user.Perms.ManagePlugins { return common.NoPermissions(w, r, user) } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } plugin, ok := common.Plugins[uname] if !ok { @@ -968,9 +901,6 @@ func routePanelPluginsInstall(w http.ResponseWriter, r *http.Request, user commo if !user.Perms.ManagePlugins { return common.NoPermissions(w, r, user) } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } plugin, ok := common.Plugins[uname] if !ok { @@ -1096,7 +1026,6 @@ func routePanelUsersEdit(w http.ResponseWriter, r *http.Request, user common.Use if ferr != nil { return ferr } - if !user.Perms.EditUser { return common.NoPermissions(w, r, user) } @@ -1155,9 +1084,6 @@ func routePanelUsersEditSubmit(w http.ResponseWriter, r *http.Request, user comm if !user.Perms.EditUser { return common.NoPermissions(w, r, user) } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } uid, err := strconv.Atoi(suid) if err != nil { @@ -1434,9 +1360,6 @@ func routePanelGroupsEditSubmit(w http.ResponseWriter, r *http.Request, user com if !user.Perms.EditGroup { return common.NoPermissions(w, r, user) } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } gid, err := strconv.Atoi(sgid) if err != nil { @@ -1527,9 +1450,6 @@ func routePanelGroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, use if !user.Perms.EditGroup { return common.NoPermissions(w, r, user) } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } gid, err := strconv.Atoi(sgid) if err != nil { @@ -1551,7 +1471,6 @@ func routePanelGroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, use return common.LocalError("You need the EditGroupSuperMod permission to edit a super-mod group.", w, r, user) } - ////var lpmap map[string]bool = make(map[string]bool) var pmap = make(map[string]bool) if user.Perms.EditGroupLocalPerms { for _, perm := range common.LocalPermList { @@ -1560,7 +1479,6 @@ func routePanelGroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, use } } - ////var gpmap map[string]bool = make(map[string]bool) if user.Perms.EditGroupGlobalPerms { for _, perm := range common.GlobalPermList { pvalue := r.PostFormValue("group-perm-" + perm) @@ -1593,9 +1511,6 @@ func routePanelGroupsCreateSubmit(w http.ResponseWriter, r *http.Request, user c if !user.Perms.EditGroup { return common.NoPermissions(w, r, user) } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } groupName := r.PostFormValue("group-name") if groupName == "" { @@ -1673,9 +1588,6 @@ func routePanelThemesSetDefault(w http.ResponseWriter, r *http.Request, user com if !user.Perms.ManageThemes { return common.NoPermissions(w, r, user) } - if r.FormValue("session") != user.Session { - return common.SecurityError(w, r, user) - } theme, ok := common.Themes[uname] if !ok { @@ -1686,7 +1598,6 @@ func routePanelThemesSetDefault(w http.ResponseWriter, r *http.Request, user com } var isDefault bool - log.Print("uname", uname) // TODO: Do we need to log this? err := stmts.isThemeDefault.QueryRow(uname).Scan(&isDefault) if err != nil && err != ErrNoRows { return common.InternalError(err, w, r) @@ -1694,19 +1605,15 @@ func routePanelThemesSetDefault(w http.ResponseWriter, r *http.Request, user com hasTheme := err != ErrNoRows if hasTheme { - log.Print("isDefault", isDefault) // TODO: Do we need to log this? if isDefault { return common.LocalError("The theme is already active", w, r, user) } _, err = stmts.updateTheme.Exec(1, uname) - if err != nil { - return common.InternalError(err, w, r) - } } else { - _, err := stmts.addTheme.Exec(uname, 1) - if err != nil { - return common.InternalError(err, w, r) - } + _, err = stmts.addTheme.Exec(uname, 1) + } + if err != nil { + return common.InternalError(err, w, r) } // TODO: Make this less racey @@ -1908,9 +1815,6 @@ func routePanelDebug(w http.ResponseWriter, r *http.Request, user common.User) c if ferr != nil { return ferr } - if !user.IsAdmin { - return common.NoPermissions(w, r, user) - } uptime := "..." dbStats := db.Stats() diff --git a/query_gen/lib/accumulator.go b/query_gen/lib/accumulator.go index e0c5363e..59a85792 100644 --- a/query_gen/lib/accumulator.go +++ b/query_gen/lib/accumulator.go @@ -271,6 +271,14 @@ func (selectItem *selectBuilder) Prepare() *sql.Stmt { return selectItem.build.SimpleSelect(selectItem.table, selectItem.columns, selectItem.where, selectItem.orderby, selectItem.limit) } +func (selectItem *selectBuilder) Query(args ...interface{}) (*sql.Rows, error) { + stmt := selectItem.Prepare() + if stmt != nil { + return stmt.Query(args...) + } + return nil, selectItem.FirstError() +} + func (build *accBuilder) Insert(table string) *insertBuilder { return &insertBuilder{table, "", "", build} } diff --git a/router_gen/routes.go b/router_gen/routes.go index aa731b21..4484886e 100644 --- a/router_gen/routes.go +++ b/router_gen/routes.go @@ -62,45 +62,45 @@ func buildPanelRoutes() { panelGroup.Routes( Route("routePanel", "/panel/"), Route("routePanelForums", "/panel/forums/"), - Route("routePanelForumsCreateSubmit", "/panel/forums/create/"), - Route("routePanelForumsDelete", "/panel/forums/delete/", "extra_data"), - Route("routePanelForumsDeleteSubmit", "/panel/forums/delete/submit/", "extra_data"), + Route("routePanelForumsCreateSubmit", "/panel/forums/create/").Before("NoSessionMismatch"), + Route("routePanelForumsDelete", "/panel/forums/delete/", "extra_data").Before("NoSessionMismatch"), + Route("routePanelForumsDeleteSubmit", "/panel/forums/delete/submit/", "extra_data").Before("NoSessionMismatch"), Route("routePanelForumsEdit", "/panel/forums/edit/", "extra_data"), - Route("routePanelForumsEditSubmit", "/panel/forums/edit/submit/", "extra_data"), - Route("routePanelForumsEditPermsSubmit", "/panel/forums/edit/perms/submit/", "extra_data"), + Route("routePanelForumsEditSubmit", "/panel/forums/edit/submit/", "extra_data").Before("NoSessionMismatch"), + Route("routePanelForumsEditPermsSubmit", "/panel/forums/edit/perms/submit/", "extra_data").Before("NoSessionMismatch"), Route("routePanelSettings", "/panel/settings/"), Route("routePanelSetting", "/panel/settings/edit/", "extra_data"), - Route("routePanelSettingEdit", "/panel/settings/edit/submit/", "extra_data"), + Route("routePanelSettingEdit", "/panel/settings/edit/submit/", "extra_data").Before("NoSessionMismatch"), Route("routePanelWordFilters", "/panel/settings/word-filters/"), - Route("routePanelWordFiltersCreate", "/panel/settings/word-filters/create/"), + Route("routePanelWordFiltersCreate", "/panel/settings/word-filters/create/").Before("ParseForm"), Route("routePanelWordFiltersEdit", "/panel/settings/word-filters/edit/", "extra_data"), - Route("routePanelWordFiltersEditSubmit", "/panel/settings/word-filters/edit/submit/", "extra_data"), - Route("routePanelWordFiltersDeleteSubmit", "/panel/settings/word-filters/delete/submit/", "extra_data"), + Route("routePanelWordFiltersEditSubmit", "/panel/settings/word-filters/edit/submit/", "extra_data").Before("ParseForm"), + Route("routePanelWordFiltersDeleteSubmit", "/panel/settings/word-filters/delete/submit/", "extra_data").Before("ParseForm"), Route("routePanelThemes", "/panel/themes/"), - Route("routePanelThemesSetDefault", "/panel/themes/default/", "extra_data"), + Route("routePanelThemesSetDefault", "/panel/themes/default/", "extra_data").Before("NoSessionMismatch"), Route("routePanelPlugins", "/panel/plugins/"), - Route("routePanelPluginsActivate", "/panel/plugins/activate/", "extra_data"), - Route("routePanelPluginsDeactivate", "/panel/plugins/deactivate/", "extra_data"), - Route("routePanelPluginsInstall", "/panel/plugins/install/", "extra_data"), + Route("routePanelPluginsActivate", "/panel/plugins/activate/", "extra_data").Before("NoSessionMismatch"), + Route("routePanelPluginsDeactivate", "/panel/plugins/deactivate/", "extra_data").Before("NoSessionMismatch"), + Route("routePanelPluginsInstall", "/panel/plugins/install/", "extra_data").Before("NoSessionMismatch"), Route("routePanelUsers", "/panel/users/"), Route("routePanelUsersEdit", "/panel/users/edit/", "extra_data"), - Route("routePanelUsersEditSubmit", "/panel/users/edit/submit/", "extra_data"), + Route("routePanelUsersEditSubmit", "/panel/users/edit/submit/", "extra_data").Before("NoSessionMismatch"), Route("routePanelGroups", "/panel/groups/"), Route("routePanelGroupsEdit", "/panel/groups/edit/", "extra_data"), Route("routePanelGroupsEditPerms", "/panel/groups/edit/perms/", "extra_data"), - Route("routePanelGroupsEditSubmit", "/panel/groups/edit/submit/", "extra_data"), - Route("routePanelGroupsEditPermsSubmit", "/panel/groups/edit/perms/submit/", "extra_data"), - Route("routePanelGroupsCreateSubmit", "/panel/groups/create/"), + Route("routePanelGroupsEditSubmit", "/panel/groups/edit/submit/", "extra_data").Before("NoSessionMismatch"), + Route("routePanelGroupsEditPermsSubmit", "/panel/groups/edit/perms/submit/", "extra_data").Before("NoSessionMismatch"), + Route("routePanelGroupsCreateSubmit", "/panel/groups/create/").Before("NoSessionMismatch"), Route("routePanelBackups", "/panel/backups/", "extra_data"), Route("routePanelLogsMod", "/panel/logs/mod/"), - Route("routePanelDebug", "/panel/debug/"), + Route("routePanelDebug", "/panel/debug/").Before("AdminOnly"), ) addRouteGroup(panelGroup) } diff --git a/routes.go b/routes.go index 10a8a684..1f217a3e 100644 --- a/routes.go +++ b/routes.go @@ -202,6 +202,7 @@ func routeTopics(w http.ResponseWriter, r *http.Request, user common.User) commo if err != nil { return common.InternalError(err, w, r) } + defer topicCountStmt.Close() var topicCount int err = topicCountStmt.QueryRow(argList...).Scan(&topicCount) @@ -229,6 +230,7 @@ func routeTopics(w http.ResponseWriter, r *http.Request, user common.User) commo if err != nil { return common.InternalError(err, w, r) } + defer stmt.Close() argList = append(argList, offset) argList = append(argList, common.Config.ItemsPerPage)