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.
This commit is contained in:
Azareal 2017-11-11 23:34:27 +00:00
parent 7ac3de8299
commit 6bae378db0
20 changed files with 338 additions and 241 deletions

37
common/audit_logs.go Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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)
_, 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,20 +1605,16 @@ 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)
_, err = stmts.addTheme.Exec(uname, 1)
}
if err != nil {
return common.InternalError(err, w, r)
}
}
// TODO: Make this less racey
// TODO: Move this to common
@ -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()

View File

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

View File

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

View File

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