More refactoring. So much data o.o
Fixed the tests. Added wrapper functions for the various logging levels. Added the SetPreset method to *Forum. Added the ReloadGroup to the ForumPermsStore.
This commit is contained in:
parent
0572c3e048
commit
b42181c0c6
|
@ -2,6 +2,7 @@ package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"log"
|
||||||
|
|
||||||
"../query_gen/lib"
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
@ -82,3 +83,27 @@ func (inits dbInits) Run() error {
|
||||||
func (inits dbInits) Add(init ...func(acc *qgen.Accumulator) error) {
|
func (inits dbInits) Add(init ...func(acc *qgen.Accumulator) error) {
|
||||||
DbInits = dbInits(append(DbInits, init...))
|
DbInits = dbInits(append(DbInits, init...))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func debugDetail(args ...interface{}) {
|
||||||
|
if Dev.SuperDebug {
|
||||||
|
log.Print(args...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func debugDetailf(str string, args ...interface{}) {
|
||||||
|
if Dev.SuperDebug {
|
||||||
|
log.Printf(str, args...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func debugLog(args ...interface{}) {
|
||||||
|
if Dev.DebugMode {
|
||||||
|
log.Print(args...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func debugLogf(str string, args ...interface{}) {
|
||||||
|
if Dev.DebugMode {
|
||||||
|
log.Printf(str, args...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package common
|
||||||
//import "fmt"
|
//import "fmt"
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"errors"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ type ForumSimple struct {
|
||||||
|
|
||||||
type ForumStmts struct {
|
type ForumStmts struct {
|
||||||
update *sql.Stmt
|
update *sql.Stmt
|
||||||
|
setPreset *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
var forumStmts ForumStmts
|
var forumStmts ForumStmts
|
||||||
|
@ -57,6 +59,7 @@ func init() {
|
||||||
DbInits.Add(func(acc *qgen.Accumulator) error {
|
DbInits.Add(func(acc *qgen.Accumulator) error {
|
||||||
forumStmts = ForumStmts{
|
forumStmts = ForumStmts{
|
||||||
update: acc.Update("forums").Set("name = ?, desc = ?, active = ?, preset = ?").Where("fid = ?").Prepare(),
|
update: acc.Update("forums").Set("name = ?, desc = ?, active = ?, preset = ?").Where("fid = ?").Prepare(),
|
||||||
|
setPreset: acc.Update("forums").Set("preset = ?").Where("fid = ?").Prepare(),
|
||||||
}
|
}
|
||||||
return acc.FirstError()
|
return acc.FirstError()
|
||||||
})
|
})
|
||||||
|
@ -88,6 +91,39 @@ func (forum *Forum) Update(name string, desc string, active bool, preset string)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (forum *Forum) SetPreset(preset string, gid int) error {
|
||||||
|
fperms, changed := GroupForumPresetToForumPerms(preset)
|
||||||
|
if changed {
|
||||||
|
return forum.setPreset(fperms, preset, gid)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Refactor this
|
||||||
|
func (forum *Forum) setPreset(fperms *ForumPerms, preset string, gid int) (err error) {
|
||||||
|
err = ReplaceForumPermsForGroup(gid, map[int]string{forum.ID: preset}, map[int]*ForumPerms{forum.ID: fperms})
|
||||||
|
if err != nil {
|
||||||
|
LogError(err)
|
||||||
|
return errors.New("Unable to update the permissions")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add this and replaceForumPermsForGroup into a transaction?
|
||||||
|
_, err = forumStmts.setPreset.Exec("", forum.ID)
|
||||||
|
if err != nil {
|
||||||
|
LogError(err)
|
||||||
|
return errors.New("Unable to update the forum")
|
||||||
|
}
|
||||||
|
err = Fstore.Reload(forum.ID)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("Unable to reload forum")
|
||||||
|
}
|
||||||
|
err = Fpstore.ReloadGroup(forum.ID, gid)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("Unable to reload the forum permissions")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Replace this sorting mechanism with something a lot more efficient
|
// TODO: Replace this sorting mechanism with something a lot more efficient
|
||||||
// ? - Use sort.Slice instead?
|
// ? - Use sort.Slice instead?
|
||||||
type SortForum []*Forum
|
type SortForum []*Forum
|
||||||
|
|
|
@ -0,0 +1,307 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"../query_gen/lib"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ? - Can we avoid duplicating the items in this list in a bunch of places?
|
||||||
|
|
||||||
|
var LocalPermList = []string{
|
||||||
|
"ViewTopic",
|
||||||
|
"LikeItem",
|
||||||
|
"CreateTopic",
|
||||||
|
"EditTopic",
|
||||||
|
"DeleteTopic",
|
||||||
|
"CreateReply",
|
||||||
|
"EditReply",
|
||||||
|
"DeleteReply",
|
||||||
|
"PinTopic",
|
||||||
|
"CloseTopic",
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inherit from group permissions for ones we don't have */
|
||||||
|
type ForumPerms struct {
|
||||||
|
ViewTopic bool
|
||||||
|
//ViewOwnTopic bool
|
||||||
|
LikeItem bool
|
||||||
|
CreateTopic bool
|
||||||
|
EditTopic bool
|
||||||
|
DeleteTopic bool
|
||||||
|
CreateReply bool
|
||||||
|
//CreateReplyToOwn bool
|
||||||
|
EditReply bool
|
||||||
|
//EditOwnReply bool
|
||||||
|
DeleteReply bool
|
||||||
|
PinTopic bool
|
||||||
|
CloseTopic bool
|
||||||
|
//CloseOwnTopic bool
|
||||||
|
|
||||||
|
Overrides bool
|
||||||
|
ExtData map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func PresetToPermmap(preset string) (out map[string]*ForumPerms) {
|
||||||
|
out = make(map[string]*ForumPerms)
|
||||||
|
switch preset {
|
||||||
|
case "all":
|
||||||
|
out["guests"] = ReadForumPerms()
|
||||||
|
out["members"] = ReadWriteForumPerms()
|
||||||
|
out["staff"] = AllForumPerms()
|
||||||
|
out["admins"] = AllForumPerms()
|
||||||
|
case "announce":
|
||||||
|
out["guests"] = ReadForumPerms()
|
||||||
|
out["members"] = ReadReplyForumPerms()
|
||||||
|
out["staff"] = AllForumPerms()
|
||||||
|
out["admins"] = AllForumPerms()
|
||||||
|
case "members":
|
||||||
|
out["guests"] = BlankForumPerms()
|
||||||
|
out["members"] = ReadWriteForumPerms()
|
||||||
|
out["staff"] = AllForumPerms()
|
||||||
|
out["admins"] = AllForumPerms()
|
||||||
|
case "staff":
|
||||||
|
out["guests"] = BlankForumPerms()
|
||||||
|
out["members"] = BlankForumPerms()
|
||||||
|
out["staff"] = ReadWriteForumPerms()
|
||||||
|
out["admins"] = AllForumPerms()
|
||||||
|
case "admins":
|
||||||
|
out["guests"] = BlankForumPerms()
|
||||||
|
out["members"] = BlankForumPerms()
|
||||||
|
out["staff"] = BlankForumPerms()
|
||||||
|
out["admins"] = AllForumPerms()
|
||||||
|
case "archive":
|
||||||
|
out["guests"] = ReadForumPerms()
|
||||||
|
out["members"] = ReadForumPerms()
|
||||||
|
out["staff"] = ReadForumPerms()
|
||||||
|
out["admins"] = ReadForumPerms() //CurateForumPerms. Delete / Edit but no create?
|
||||||
|
default:
|
||||||
|
out["guests"] = BlankForumPerms()
|
||||||
|
out["members"] = BlankForumPerms()
|
||||||
|
out["staff"] = BlankForumPerms()
|
||||||
|
out["admins"] = BlankForumPerms()
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func PermmapToQuery(permmap map[string]*ForumPerms, fid int) error {
|
||||||
|
tx, err := qgen.Builder.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
deleteForumPermsByForumTx, err := qgen.Builder.SimpleDeleteTx(tx, "forums_permissions", "fid = ?")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = deleteForumPermsByForumTx.Exec(fid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
perms, err := json.Marshal(permmap["admins"])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
addForumPermsToForumAdminsTx, err := qgen.Builder.SimpleInsertSelectTx(tx,
|
||||||
|
qgen.DBInsert{"forums_permissions", "gid, fid, preset, permissions", ""},
|
||||||
|
qgen.DBSelect{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 1", "", ""},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = addForumPermsToForumAdminsTx.Exec(fid, "", perms)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
perms, err = json.Marshal(permmap["staff"])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
addForumPermsToForumStaffTx, err := qgen.Builder.SimpleInsertSelectTx(tx,
|
||||||
|
qgen.DBInsert{"forums_permissions", "gid, fid, preset, permissions", ""},
|
||||||
|
qgen.DBSelect{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 0 AND is_mod = 1", "", ""},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = addForumPermsToForumStaffTx.Exec(fid, "", perms)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
perms, err = json.Marshal(permmap["members"])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
addForumPermsToForumMembersTx, err := qgen.Builder.SimpleInsertSelectTx(tx,
|
||||||
|
qgen.DBInsert{"forums_permissions", "gid, fid, preset, permissions", ""},
|
||||||
|
qgen.DBSelect{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 0 AND is_mod = 0 AND is_banned = 0", "", ""},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = addForumPermsToForumMembersTx.Exec(fid, "", perms)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6 is the ID of the Not Loggedin Group
|
||||||
|
// TODO: Use a shared variable rather than a literal for the group ID
|
||||||
|
err = ReplaceForumPermsForGroupTx(tx, 6, map[int]string{fid: ""}, map[int]*ForumPerms{fid: permmap["guests"]})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Fpstore.Reload(fid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReplaceForumPermsForGroup(gid int, presetSet map[int]string, permSets map[int]*ForumPerms) error {
|
||||||
|
tx, err := qgen.Builder.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer tx.Rollback()
|
||||||
|
err = ReplaceForumPermsForGroupTx(tx, gid, presetSet, permSets)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return tx.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReplaceForumPermsForGroupTx(tx *sql.Tx, gid int, presetSets map[int]string, permSets map[int]*ForumPerms) error {
|
||||||
|
deleteForumPermsForGroupTx, err := qgen.Builder.SimpleDeleteTx(tx, "forums_permissions", "gid = ? AND fid = ?")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
addForumPermsToGroupTx, err := qgen.Builder.SimpleInsertTx(tx, "forums_permissions", "gid, fid, preset, permissions", "?,?,?,?")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for fid, permSet := range permSets {
|
||||||
|
permstr, err := json.Marshal(permSet)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = deleteForumPermsForGroupTx.Exec(gid, fid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = addForumPermsToGroupTx.Exec(gid, fid, presetSets[fid], string(permstr))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Refactor this and write tests for it
|
||||||
|
func ForumPermsToGroupForumPreset(fperms *ForumPerms) string {
|
||||||
|
if !fperms.Overrides {
|
||||||
|
return "default"
|
||||||
|
}
|
||||||
|
if !fperms.ViewTopic {
|
||||||
|
return "no_access"
|
||||||
|
}
|
||||||
|
var canPost = (fperms.LikeItem && fperms.CreateTopic && fperms.CreateReply)
|
||||||
|
var canModerate = (canPost && fperms.EditTopic && fperms.DeleteTopic && fperms.EditReply && fperms.DeleteReply && fperms.PinTopic && fperms.CloseTopic)
|
||||||
|
if canModerate {
|
||||||
|
return "can_moderate"
|
||||||
|
}
|
||||||
|
if fperms.EditTopic || fperms.DeleteTopic || fperms.EditReply || fperms.DeleteReply || fperms.PinTopic || fperms.CloseTopic {
|
||||||
|
if !canPost {
|
||||||
|
return "custom"
|
||||||
|
}
|
||||||
|
return "quasi_mod"
|
||||||
|
}
|
||||||
|
|
||||||
|
if canPost {
|
||||||
|
return "can_post"
|
||||||
|
}
|
||||||
|
if fperms.ViewTopic && !fperms.LikeItem && !fperms.CreateTopic && !fperms.CreateReply {
|
||||||
|
return "read_only"
|
||||||
|
}
|
||||||
|
return "custom"
|
||||||
|
}
|
||||||
|
|
||||||
|
func GroupForumPresetToForumPerms(preset string) (fperms *ForumPerms, changed bool) {
|
||||||
|
switch preset {
|
||||||
|
case "read_only":
|
||||||
|
return ReadForumPerms(), true
|
||||||
|
case "can_post":
|
||||||
|
return ReadWriteForumPerms(), true
|
||||||
|
case "can_moderate":
|
||||||
|
return AllForumPerms(), true
|
||||||
|
case "no_access":
|
||||||
|
return &ForumPerms{Overrides: true, ExtData: make(map[string]bool)}, true
|
||||||
|
case "default":
|
||||||
|
return BlankForumPerms(), true
|
||||||
|
}
|
||||||
|
return fperms, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func BlankForumPerms() *ForumPerms {
|
||||||
|
return &ForumPerms{ViewTopic: false}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadWriteForumPerms() *ForumPerms {
|
||||||
|
return &ForumPerms{
|
||||||
|
ViewTopic: true,
|
||||||
|
LikeItem: true,
|
||||||
|
CreateTopic: true,
|
||||||
|
CreateReply: true,
|
||||||
|
Overrides: true,
|
||||||
|
ExtData: make(map[string]bool),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadReplyForumPerms() *ForumPerms {
|
||||||
|
return &ForumPerms{
|
||||||
|
ViewTopic: true,
|
||||||
|
LikeItem: true,
|
||||||
|
CreateReply: true,
|
||||||
|
Overrides: true,
|
||||||
|
ExtData: make(map[string]bool),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadForumPerms() *ForumPerms {
|
||||||
|
return &ForumPerms{
|
||||||
|
ViewTopic: true,
|
||||||
|
Overrides: true,
|
||||||
|
ExtData: make(map[string]bool),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllForumPerms is a set of forum local permissions with everything set to true
|
||||||
|
func AllForumPerms() *ForumPerms {
|
||||||
|
return &ForumPerms{
|
||||||
|
ViewTopic: true,
|
||||||
|
LikeItem: true,
|
||||||
|
CreateTopic: true,
|
||||||
|
EditTopic: true,
|
||||||
|
DeleteTopic: true,
|
||||||
|
CreateReply: true,
|
||||||
|
EditReply: true,
|
||||||
|
DeleteReply: true,
|
||||||
|
PinTopic: true,
|
||||||
|
CloseTopic: true,
|
||||||
|
|
||||||
|
Overrides: true,
|
||||||
|
ExtData: make(map[string]bool),
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"../query_gen/lib"
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
@ -12,8 +13,9 @@ var Fpstore ForumPermsStore
|
||||||
|
|
||||||
type ForumPermsStore interface {
|
type ForumPermsStore interface {
|
||||||
Init() error
|
Init() error
|
||||||
Get(fid int, gid int) (fperms ForumPerms, err error)
|
Get(fid int, gid int) (fperms *ForumPerms, err error)
|
||||||
Reload(id int) error
|
Reload(id int) error
|
||||||
|
ReloadGroup(fid int, gid int) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type ForumPermsCache interface {
|
type ForumPermsCache interface {
|
||||||
|
@ -22,6 +24,9 @@ type ForumPermsCache interface {
|
||||||
type MemoryForumPermsStore struct {
|
type MemoryForumPermsStore struct {
|
||||||
get *sql.Stmt
|
get *sql.Stmt
|
||||||
getByForum *sql.Stmt
|
getByForum *sql.Stmt
|
||||||
|
getByForumGroup *sql.Stmt
|
||||||
|
|
||||||
|
updateMutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMemoryForumPermsStore() (*MemoryForumPermsStore, error) {
|
func NewMemoryForumPermsStore() (*MemoryForumPermsStore, error) {
|
||||||
|
@ -29,72 +34,69 @@ func NewMemoryForumPermsStore() (*MemoryForumPermsStore, error) {
|
||||||
return &MemoryForumPermsStore{
|
return &MemoryForumPermsStore{
|
||||||
get: acc.Select("forums_permissions").Columns("gid, fid, permissions").Orderby("gid ASC, fid ASC").Prepare(),
|
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(),
|
getByForum: acc.Select("forums_permissions").Columns("gid, permissions").Where("fid = ?").Orderby("gid ASC").Prepare(),
|
||||||
|
getByForumGroup: acc.Select("forums_permissions").Columns("permissions").Where("fid = ? AND gid = ?").Prepare(),
|
||||||
}, acc.FirstError()
|
}, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fps *MemoryForumPermsStore) Init() error {
|
func (fps *MemoryForumPermsStore) Init() error {
|
||||||
|
fps.updateMutex.Lock()
|
||||||
|
defer fps.updateMutex.Unlock()
|
||||||
fids, err := Fstore.GetAllIDs()
|
fids, err := Fstore.GetAllIDs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if Dev.SuperDebug {
|
debugDetail("fids: ", fids)
|
||||||
log.Print("fids: ", fids)
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, err := fps.get.Query()
|
rows, err := fps.get.Query()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
debugLog("Adding the forum permissions")
|
||||||
if Dev.DebugMode {
|
debugDetail("forumPerms[gid][fid]")
|
||||||
log.Print("Adding the forum permissions")
|
|
||||||
if Dev.SuperDebug {
|
|
||||||
log.Print("forumPerms[gid][fid]")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Temporarily store the forum perms in a map before transferring it to a much faster and thread-safe slice
|
// Temporarily store the forum perms in a map before transferring it to a much faster and thread-safe slice
|
||||||
forumPerms = make(map[int]map[int]ForumPerms)
|
forumPerms = make(map[int]map[int]*ForumPerms)
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var gid, fid int
|
var gid, fid int
|
||||||
var perms []byte
|
var perms []byte
|
||||||
var pperms ForumPerms
|
|
||||||
err = rows.Scan(&gid, &fid, &perms)
|
err = rows.Scan(&gid, &fid, &perms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if Dev.SuperDebug {
|
pperms, err := fps.parseForumPerm(perms)
|
||||||
log.Print("perms: ", string(perms))
|
|
||||||
}
|
|
||||||
err = json.Unmarshal(perms, &pperms)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pperms.ExtData = make(map[string]bool)
|
|
||||||
pperms.Overrides = true
|
|
||||||
_, ok := forumPerms[gid]
|
_, ok := forumPerms[gid]
|
||||||
if !ok {
|
if !ok {
|
||||||
forumPerms[gid] = make(map[int]ForumPerms)
|
forumPerms[gid] = make(map[int]*ForumPerms)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Dev.SuperDebug {
|
debugDetail("gid: ", gid)
|
||||||
log.Print("gid: ", gid)
|
debugDetail("fid: ", fid)
|
||||||
log.Print("fid: ", fid)
|
debugDetailf("perms: %+v\n", pperms)
|
||||||
log.Printf("perms: %+v\n", pperms)
|
|
||||||
}
|
|
||||||
forumPerms[gid][fid] = pperms
|
forumPerms[gid][fid] = pperms
|
||||||
}
|
}
|
||||||
|
|
||||||
return fps.cascadePermSetToGroups(forumPerms, fids)
|
return fps.cascadePermSetToGroups(forumPerms, fids)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fps *MemoryForumPermsStore) parseForumPerm(perms []byte) (pperms *ForumPerms, err error) {
|
||||||
|
debugDetail("perms: ", string(perms))
|
||||||
|
pperms = BlankForumPerms()
|
||||||
|
err = json.Unmarshal(perms, &pperms)
|
||||||
|
pperms.ExtData = make(map[string]bool)
|
||||||
|
pperms.Overrides = true
|
||||||
|
return pperms, err
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Need a more thread-safe way of doing this. Possibly with sync.Map?
|
// TODO: Need a more thread-safe way of doing this. Possibly with sync.Map?
|
||||||
func (fps *MemoryForumPermsStore) Reload(fid int) error {
|
func (fps *MemoryForumPermsStore) Reload(fid int) error {
|
||||||
if Dev.DebugMode {
|
fps.updateMutex.Lock()
|
||||||
log.Printf("Reloading the forum permissions for forum #%d", fid)
|
defer fps.updateMutex.Unlock()
|
||||||
}
|
debugLogf("Reloading the forum permissions for forum #%d", fid)
|
||||||
fids, err := Fstore.GetAllIDs()
|
fids, err := Fstore.GetAllIDs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -109,38 +111,56 @@ func (fps *MemoryForumPermsStore) Reload(fid int) error {
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var gid int
|
var gid int
|
||||||
var perms []byte
|
var perms []byte
|
||||||
var pperms ForumPerms
|
|
||||||
err := rows.Scan(&gid, &perms)
|
err := rows.Scan(&gid, &perms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = json.Unmarshal(perms, &pperms)
|
|
||||||
|
pperms, err := fps.parseForumPerm(perms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pperms.ExtData = make(map[string]bool)
|
|
||||||
pperms.Overrides = true
|
|
||||||
_, ok := forumPerms[gid]
|
_, ok := forumPerms[gid]
|
||||||
if !ok {
|
if !ok {
|
||||||
forumPerms[gid] = make(map[int]ForumPerms)
|
forumPerms[gid] = make(map[int]*ForumPerms)
|
||||||
}
|
}
|
||||||
|
|
||||||
forumPerms[gid][fid] = pperms
|
forumPerms[gid][fid] = pperms
|
||||||
}
|
}
|
||||||
|
|
||||||
return fps.cascadePermSetToGroups(forumPerms, fids)
|
return fps.cascadePermSetToGroups(forumPerms, fids)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fps *MemoryForumPermsStore) cascadePermSetToGroups(forumPerms map[int]map[int]ForumPerms, fids []int) error {
|
func (fps *MemoryForumPermsStore) ReloadGroup(fid int, gid int) (err error) {
|
||||||
|
fps.updateMutex.Lock()
|
||||||
|
defer fps.updateMutex.Unlock()
|
||||||
|
var perms []byte
|
||||||
|
err = fps.getByForumGroup.QueryRow(fid, gid).Scan(&perms)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fperms, err := fps.parseForumPerm(perms)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
group, err := Gstore.Get(gid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// TODO: Refactor this
|
||||||
|
group.Forums[fid] = fperms
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fps *MemoryForumPermsStore) cascadePermSetToGroups(forumPerms map[int]map[int]*ForumPerms, fids []int) error {
|
||||||
groups, err := Gstore.GetAll()
|
groups, err := Gstore.GetAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, group := range groups {
|
for _, group := range groups {
|
||||||
if Dev.DebugMode {
|
debugLogf("Updating the forum permissions for Group #%d", group.ID)
|
||||||
log.Printf("Updating the forum permissions for Group #%d", group.ID)
|
group.Forums = []*ForumPerms{BlankForumPerms()}
|
||||||
}
|
|
||||||
group.Forums = []ForumPerms{BlankForumPerms}
|
|
||||||
group.CanSee = []int{}
|
group.CanSee = []int{}
|
||||||
fps.cascadePermSetToGroup(forumPerms, group, fids)
|
fps.cascadePermSetToGroup(forumPerms, group, fids)
|
||||||
|
|
||||||
|
@ -152,18 +172,16 @@ func (fps *MemoryForumPermsStore) cascadePermSetToGroups(forumPerms map[int]map[
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[int]ForumPerms, group *Group, fids []int) {
|
func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[int]*ForumPerms, group *Group, fids []int) {
|
||||||
for _, fid := range fids {
|
for _, fid := range fids {
|
||||||
if Dev.SuperDebug {
|
debugDetailf("Forum #%+v\n", fid)
|
||||||
log.Printf("Forum #%+v\n", fid)
|
|
||||||
}
|
|
||||||
forumPerm, ok := forumPerms[group.ID][fid]
|
forumPerm, ok := forumPerms[group.ID][fid]
|
||||||
if ok {
|
if ok {
|
||||||
//log.Printf("Overriding permissions for forum #%d",fid)
|
//log.Printf("Overriding permissions for forum #%d",fid)
|
||||||
group.Forums = append(group.Forums, forumPerm)
|
group.Forums = append(group.Forums, forumPerm)
|
||||||
} else {
|
} else {
|
||||||
//log.Printf("Inheriting from group defaults for forum #%d",fid)
|
//log.Printf("Inheriting from group defaults for forum #%d",fid)
|
||||||
forumPerm = BlankForumPerms
|
forumPerm = BlankForumPerms()
|
||||||
group.Forums = append(group.Forums, forumPerm)
|
group.Forums = append(group.Forums, forumPerm)
|
||||||
}
|
}
|
||||||
if forumPerm.Overrides {
|
if forumPerm.Overrides {
|
||||||
|
@ -174,16 +192,14 @@ func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[i
|
||||||
group.CanSee = append(group.CanSee, fid)
|
group.CanSee = append(group.CanSee, fid)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Dev.SuperDebug {
|
debugDetail("group.ID: ", group.ID)
|
||||||
log.Print("group.ID: ", group.ID)
|
debugDetailf("forumPerm: %+v\n", forumPerm)
|
||||||
log.Printf("forumPerm: %+v\n", forumPerm)
|
debugDetail("group.CanSee: ", group.CanSee)
|
||||||
log.Print("group.CanSee: ", group.CanSee)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fps *MemoryForumPermsStore) Get(fid int, gid int) (fperms ForumPerms, err error) {
|
|
||||||
// TODO: Add a hook here and have plugin_guilds use it
|
// TODO: Add a hook here and have plugin_guilds use it
|
||||||
|
func (fps *MemoryForumPermsStore) Get(fid int, gid int) (fperms *ForumPerms, err error) {
|
||||||
group, err := Gstore.Get(gid)
|
group, err := Gstore.Get(gid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fperms, ErrNoRows
|
return fperms, ErrNoRows
|
||||||
|
|
|
@ -17,9 +17,8 @@ import (
|
||||||
"../query_gen/lib"
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ForumUpdateMutex sync.Mutex
|
|
||||||
var forumCreateMutex sync.Mutex
|
var forumCreateMutex sync.Mutex
|
||||||
var forumPerms map[int]map[int]ForumPerms // [gid][fid]Perms // TODO: Add an abstraction around this and make it more thread-safe
|
var forumPerms map[int]map[int]*ForumPerms // [gid][fid]*ForumPerms // TODO: Add an abstraction around this and make it more thread-safe
|
||||||
var Fstore ForumStore
|
var Fstore ForumStore
|
||||||
|
|
||||||
// ForumStore is an interface for accessing the forums and the metadata stored on them
|
// ForumStore is an interface for accessing the forums and the metadata stored on them
|
||||||
|
@ -110,9 +109,7 @@ func (mfs *MemoryForumStore) LoadForums() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if forum.Name == "" {
|
if forum.Name == "" {
|
||||||
if Dev.DebugMode {
|
debugLog("Adding a placeholder forum")
|
||||||
log.Print("Adding a placeholder forum")
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Adding the '%s' forum", forum.Name)
|
log.Printf("Adding the '%s' forum", forum.Name)
|
||||||
}
|
}
|
||||||
|
@ -272,11 +269,8 @@ func (mfs *MemoryForumStore) Delete(id int) error {
|
||||||
return errors.New("You cannot delete the Reports forum")
|
return errors.New("You cannot delete the Reports forum")
|
||||||
}
|
}
|
||||||
_, err := mfs.delete.Exec(id)
|
_, err := mfs.delete.Exec(id)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
mfs.CacheDelete(id)
|
mfs.CacheDelete(id)
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mfs *MemoryForumStore) AddTopic(tid int, uid int, fid int) error {
|
func (mfs *MemoryForumStore) AddTopic(tid int, uid int, fid int) error {
|
||||||
|
|
|
@ -26,7 +26,7 @@ type Group struct {
|
||||||
PermissionsText []byte
|
PermissionsText []byte
|
||||||
PluginPerms map[string]bool // Custom permissions defined by plugins. What if two plugins declare the same permission, but they handle them in incompatible ways? Very unlikely, we probably don't need to worry about this, the plugin authors should be aware of each other to some extent
|
PluginPerms map[string]bool // Custom permissions defined by plugins. What if two plugins declare the same permission, but they handle them in incompatible ways? Very unlikely, we probably don't need to worry about this, the plugin authors should be aware of each other to some extent
|
||||||
PluginPermsText []byte
|
PluginPermsText []byte
|
||||||
Forums []ForumPerms
|
Forums []*ForumPerms
|
||||||
CanSee []int // The IDs of the forums this group can see
|
CanSee []int // The IDs of the forums this group can see
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,9 +86,7 @@ func (mgs *MemoryGroupStore) LoadGroups() error {
|
||||||
}
|
}
|
||||||
mgs.groupCount = i
|
mgs.groupCount = i
|
||||||
|
|
||||||
if Dev.DebugMode {
|
debugLog("Binding the Not Loggedin Group")
|
||||||
log.Print("Binding the Not Loggedin Group")
|
|
||||||
}
|
|
||||||
GuestPerms = mgs.dirtyGetUnsafe(6).Perms
|
GuestPerms = mgs.dirtyGetUnsafe(6).Perms
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -172,9 +170,7 @@ func (mgs *MemoryGroupStore) initGroup(group *Group) error {
|
||||||
log.Print("bad group plugin perms: ", group.PluginPermsText)
|
log.Print("bad group plugin perms: ", group.PluginPermsText)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if Dev.DebugMode {
|
debugLogf(group.Name+": %+v\n", group.PluginPerms)
|
||||||
log.Printf(group.Name+": %+v\n", group.PluginPerms)
|
|
||||||
}
|
|
||||||
|
|
||||||
//group.Perms.ExtData = make(map[string]bool)
|
//group.Perms.ExtData = make(map[string]bool)
|
||||||
// TODO: Can we optimise the bit where this cascades down to the user now?
|
// TODO: Can we optimise the bit where this cascades down to the user now?
|
||||||
|
@ -200,6 +196,7 @@ func (mgs *MemoryGroupStore) Exists(gid int) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ? Allow two groups with the same name?
|
// ? Allow two groups with the same name?
|
||||||
|
// TODO: Refactor this
|
||||||
func (mgs *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod bool, isBanned bool) (gid int, err error) {
|
func (mgs *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod bool, isBanned bool) (gid int, err error) {
|
||||||
var permstr = "{}"
|
var permstr = "{}"
|
||||||
tx, err := qgen.Builder.Begin()
|
tx, err := qgen.Builder.Begin()
|
||||||
|
@ -224,7 +221,7 @@ func (mgs *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod
|
||||||
gid = int(gid64)
|
gid = int(gid64)
|
||||||
|
|
||||||
var perms = BlankPerms
|
var perms = BlankPerms
|
||||||
var blankForums []ForumPerms
|
var blankForums []*ForumPerms
|
||||||
var blankIntList []int
|
var blankIntList []int
|
||||||
var pluginPerms = make(map[string]bool)
|
var pluginPerms = make(map[string]bool)
|
||||||
var pluginPermsBytes = []byte("{}")
|
var pluginPermsBytes = []byte("{}")
|
||||||
|
@ -239,18 +236,17 @@ func (mgs *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod
|
||||||
}
|
}
|
||||||
|
|
||||||
var presetSet = make(map[int]string)
|
var presetSet = make(map[int]string)
|
||||||
var permSet = make(map[int]ForumPerms)
|
var permSet = make(map[int]*ForumPerms)
|
||||||
PermUpdateMutex.Lock()
|
|
||||||
defer PermUpdateMutex.Unlock()
|
|
||||||
for _, forum := range fdata {
|
for _, forum := range fdata {
|
||||||
var thePreset string
|
var thePreset string
|
||||||
if isAdmin {
|
switch {
|
||||||
|
case isAdmin:
|
||||||
thePreset = "admins"
|
thePreset = "admins"
|
||||||
} else if isMod {
|
case isMod:
|
||||||
thePreset = "staff"
|
thePreset = "staff"
|
||||||
} else if isBanned {
|
case isBanned:
|
||||||
thePreset = "banned"
|
thePreset = "banned"
|
||||||
} else {
|
default:
|
||||||
thePreset = "members"
|
thePreset = "members"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,46 +1,20 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"../query_gen/lib"
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Refactor the perms system
|
// TODO: Refactor the perms system
|
||||||
|
|
||||||
var PermUpdateMutex sync.Mutex
|
|
||||||
var BlankPerms Perms
|
var BlankPerms Perms
|
||||||
var BlankForumPerms ForumPerms
|
|
||||||
var GuestPerms Perms
|
var GuestPerms Perms
|
||||||
var ReadForumPerms ForumPerms
|
|
||||||
var ReadReplyForumPerms ForumPerms
|
|
||||||
var ReadWriteForumPerms ForumPerms
|
|
||||||
|
|
||||||
// AllPerms is a set of global permissions with everything set to true
|
// AllPerms is a set of global permissions with everything set to true
|
||||||
var AllPerms Perms
|
var AllPerms Perms
|
||||||
|
|
||||||
// AllForumPerms is a set of forum local permissions with everything set to true
|
|
||||||
var AllForumPerms ForumPerms
|
|
||||||
var AllPluginPerms = make(map[string]bool)
|
var AllPluginPerms = make(map[string]bool)
|
||||||
|
|
||||||
// ? - Can we avoid duplicating the items in this list in a bunch of places?
|
|
||||||
|
|
||||||
var LocalPermList = []string{
|
|
||||||
"ViewTopic",
|
|
||||||
"LikeItem",
|
|
||||||
"CreateTopic",
|
|
||||||
"EditTopic",
|
|
||||||
"DeleteTopic",
|
|
||||||
"CreateReply",
|
|
||||||
"EditReply",
|
|
||||||
"DeleteReply",
|
|
||||||
"PinTopic",
|
|
||||||
"CloseTopic",
|
|
||||||
}
|
|
||||||
|
|
||||||
// ? - Can we avoid duplicating the items in this list in a bunch of places?
|
// ? - Can we avoid duplicating the items in this list in a bunch of places?
|
||||||
var GlobalPermList = []string{
|
var GlobalPermList = []string{
|
||||||
"BanUsers",
|
"BanUsers",
|
||||||
|
@ -111,36 +85,11 @@ type Perms struct {
|
||||||
//ExtData map[string]bool
|
//ExtData map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inherit from group permissions for ones we don't have */
|
|
||||||
type ForumPerms struct {
|
|
||||||
ViewTopic bool
|
|
||||||
//ViewOwnTopic bool
|
|
||||||
LikeItem bool
|
|
||||||
CreateTopic bool
|
|
||||||
EditTopic bool
|
|
||||||
DeleteTopic bool
|
|
||||||
CreateReply bool
|
|
||||||
//CreateReplyToOwn bool
|
|
||||||
EditReply bool
|
|
||||||
//EditOwnReply bool
|
|
||||||
DeleteReply bool
|
|
||||||
PinTopic bool
|
|
||||||
CloseTopic bool
|
|
||||||
//CloseOwnTopic bool
|
|
||||||
|
|
||||||
Overrides bool
|
|
||||||
ExtData map[string]bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
BlankPerms = Perms{
|
BlankPerms = Perms{
|
||||||
//ExtData: make(map[string]bool),
|
//ExtData: make(map[string]bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
BlankForumPerms = ForumPerms{
|
|
||||||
ExtData: make(map[string]bool),
|
|
||||||
}
|
|
||||||
|
|
||||||
GuestPerms = Perms{
|
GuestPerms = Perms{
|
||||||
ViewTopic: true,
|
ViewTopic: true,
|
||||||
//ExtData: make(map[string]bool),
|
//ExtData: make(map[string]bool),
|
||||||
|
@ -183,266 +132,9 @@ func init() {
|
||||||
//ExtData: make(map[string]bool),
|
//ExtData: make(map[string]bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
AllForumPerms = ForumPerms{
|
|
||||||
ViewTopic: true,
|
|
||||||
LikeItem: true,
|
|
||||||
CreateTopic: true,
|
|
||||||
EditTopic: true,
|
|
||||||
DeleteTopic: true,
|
|
||||||
CreateReply: true,
|
|
||||||
EditReply: true,
|
|
||||||
DeleteReply: true,
|
|
||||||
PinTopic: true,
|
|
||||||
CloseTopic: true,
|
|
||||||
|
|
||||||
Overrides: true,
|
|
||||||
ExtData: make(map[string]bool),
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadWriteForumPerms = ForumPerms{
|
|
||||||
ViewTopic: true,
|
|
||||||
LikeItem: true,
|
|
||||||
CreateTopic: true,
|
|
||||||
CreateReply: true,
|
|
||||||
Overrides: true,
|
|
||||||
ExtData: make(map[string]bool),
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadReplyForumPerms = ForumPerms{
|
|
||||||
ViewTopic: true,
|
|
||||||
LikeItem: true,
|
|
||||||
CreateReply: true,
|
|
||||||
Overrides: true,
|
|
||||||
ExtData: make(map[string]bool),
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadForumPerms = ForumPerms{
|
|
||||||
ViewTopic: true,
|
|
||||||
Overrides: true,
|
|
||||||
ExtData: make(map[string]bool),
|
|
||||||
}
|
|
||||||
|
|
||||||
GuestUser.Perms = GuestPerms
|
GuestUser.Perms = GuestPerms
|
||||||
|
debugLogf("Guest Perms: %+v\n", GuestPerms)
|
||||||
if Dev.DebugMode {
|
debugLogf("All Perms: %+v\n", AllPerms)
|
||||||
log.Printf("Guest Perms: %+v\n", GuestPerms)
|
|
||||||
log.Printf("All Perms: %+v\n", AllPerms)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PresetToPermmap(preset string) (out map[string]ForumPerms) {
|
|
||||||
out = make(map[string]ForumPerms)
|
|
||||||
switch preset {
|
|
||||||
case "all":
|
|
||||||
out["guests"] = ReadForumPerms
|
|
||||||
out["members"] = ReadWriteForumPerms
|
|
||||||
out["staff"] = AllForumPerms
|
|
||||||
out["admins"] = AllForumPerms
|
|
||||||
case "announce":
|
|
||||||
out["guests"] = ReadForumPerms
|
|
||||||
out["members"] = ReadReplyForumPerms
|
|
||||||
out["staff"] = AllForumPerms
|
|
||||||
out["admins"] = AllForumPerms
|
|
||||||
case "members":
|
|
||||||
out["guests"] = BlankForumPerms
|
|
||||||
out["members"] = ReadWriteForumPerms
|
|
||||||
out["staff"] = AllForumPerms
|
|
||||||
out["admins"] = AllForumPerms
|
|
||||||
case "staff":
|
|
||||||
out["guests"] = BlankForumPerms
|
|
||||||
out["members"] = BlankForumPerms
|
|
||||||
out["staff"] = ReadWriteForumPerms
|
|
||||||
out["admins"] = AllForumPerms
|
|
||||||
case "admins":
|
|
||||||
out["guests"] = BlankForumPerms
|
|
||||||
out["members"] = BlankForumPerms
|
|
||||||
out["staff"] = BlankForumPerms
|
|
||||||
out["admins"] = AllForumPerms
|
|
||||||
case "archive":
|
|
||||||
out["guests"] = ReadForumPerms
|
|
||||||
out["members"] = ReadForumPerms
|
|
||||||
out["staff"] = ReadForumPerms
|
|
||||||
out["admins"] = ReadForumPerms //CurateForumPerms. Delete / Edit but no create?
|
|
||||||
default:
|
|
||||||
out["guests"] = BlankForumPerms
|
|
||||||
out["members"] = BlankForumPerms
|
|
||||||
out["staff"] = BlankForumPerms
|
|
||||||
out["admins"] = BlankForumPerms
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func PermmapToQuery(permmap map[string]ForumPerms, fid int) error {
|
|
||||||
tx, err := qgen.Builder.Begin()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer tx.Rollback()
|
|
||||||
|
|
||||||
deleteForumPermsByForumTx, err := qgen.Builder.SimpleDeleteTx(tx, "forums_permissions", "fid = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = deleteForumPermsByForumTx.Exec(fid)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
perms, err := json.Marshal(permmap["admins"])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
addForumPermsToForumAdminsTx, err := qgen.Builder.SimpleInsertSelectTx(tx,
|
|
||||||
qgen.DBInsert{"forums_permissions", "gid, fid, preset, permissions", ""},
|
|
||||||
qgen.DBSelect{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 1", "", ""},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = addForumPermsToForumAdminsTx.Exec(fid, "", perms)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
perms, err = json.Marshal(permmap["staff"])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
addForumPermsToForumStaffTx, err := qgen.Builder.SimpleInsertSelectTx(tx,
|
|
||||||
qgen.DBInsert{"forums_permissions", "gid, fid, preset, permissions", ""},
|
|
||||||
qgen.DBSelect{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 0 AND is_mod = 1", "", ""},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = addForumPermsToForumStaffTx.Exec(fid, "", perms)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
perms, err = json.Marshal(permmap["members"])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
addForumPermsToForumMembersTx, err := qgen.Builder.SimpleInsertSelectTx(tx,
|
|
||||||
qgen.DBInsert{"forums_permissions", "gid, fid, preset, permissions", ""},
|
|
||||||
qgen.DBSelect{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 0 AND is_mod = 0 AND is_banned = 0", "", ""},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = addForumPermsToForumMembersTx.Exec(fid, "", perms)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6 is the ID of the Not Loggedin Group
|
|
||||||
// TODO: Use a shared variable rather than a literal for the group ID
|
|
||||||
err = ReplaceForumPermsForGroupTx(tx, 6, map[int]string{fid: ""}, map[int]ForumPerms{fid: permmap["guests"]})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = tx.Commit()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
PermUpdateMutex.Lock()
|
|
||||||
defer PermUpdateMutex.Unlock()
|
|
||||||
return Fpstore.Reload(fid)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ReplaceForumPermsForGroup(gid int, presetSet map[int]string, permSets map[int]ForumPerms) error {
|
|
||||||
tx, err := qgen.Builder.Begin()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer tx.Rollback()
|
|
||||||
err = ReplaceForumPermsForGroupTx(tx, gid, presetSet, permSets)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return tx.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
func ReplaceForumPermsForGroupTx(tx *sql.Tx, gid int, presetSets map[int]string, permSets map[int]ForumPerms) error {
|
|
||||||
deleteForumPermsForGroupTx, err := qgen.Builder.SimpleDeleteTx(tx, "forums_permissions", "gid = ? AND fid = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
addForumPermsToGroupTx, err := qgen.Builder.SimpleInsertTx(tx, "forums_permissions", "gid, fid, preset, permissions", "?,?,?,?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for fid, permSet := range permSets {
|
|
||||||
permstr, err := json.Marshal(permSet)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = deleteForumPermsForGroupTx.Exec(gid, fid)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = addForumPermsToGroupTx.Exec(gid, fid, presetSets[fid], string(permstr))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Refactor this and write tests for it
|
|
||||||
func ForumPermsToGroupForumPreset(fperms ForumPerms) string {
|
|
||||||
if !fperms.Overrides {
|
|
||||||
return "default"
|
|
||||||
}
|
|
||||||
if !fperms.ViewTopic {
|
|
||||||
return "no_access"
|
|
||||||
}
|
|
||||||
var canPost = (fperms.LikeItem && fperms.CreateTopic && fperms.CreateReply)
|
|
||||||
var canModerate = (canPost && fperms.EditTopic && fperms.DeleteTopic && fperms.EditReply && fperms.DeleteReply && fperms.PinTopic && fperms.CloseTopic)
|
|
||||||
if canModerate {
|
|
||||||
return "can_moderate"
|
|
||||||
}
|
|
||||||
if fperms.EditTopic || fperms.DeleteTopic || fperms.EditReply || fperms.DeleteReply || fperms.PinTopic || fperms.CloseTopic {
|
|
||||||
if !canPost {
|
|
||||||
return "custom"
|
|
||||||
}
|
|
||||||
return "quasi_mod"
|
|
||||||
}
|
|
||||||
|
|
||||||
if canPost {
|
|
||||||
return "can_post"
|
|
||||||
}
|
|
||||||
if fperms.ViewTopic && !fperms.LikeItem && !fperms.CreateTopic && !fperms.CreateReply {
|
|
||||||
return "read_only"
|
|
||||||
}
|
|
||||||
return "custom"
|
|
||||||
}
|
|
||||||
|
|
||||||
func GroupForumPresetToForumPerms(preset string) (fperms ForumPerms, changed bool) {
|
|
||||||
switch preset {
|
|
||||||
case "read_only":
|
|
||||||
return ReadForumPerms, true
|
|
||||||
case "can_post":
|
|
||||||
return ReadWriteForumPerms, true
|
|
||||||
case "can_moderate":
|
|
||||||
return AllForumPerms, true
|
|
||||||
case "no_access":
|
|
||||||
return ForumPerms{Overrides: true, ExtData: make(map[string]bool)}, true
|
|
||||||
case "default":
|
|
||||||
return BlankForumPerms, true
|
|
||||||
//case "custom": return fperms, false
|
|
||||||
}
|
|
||||||
return fperms, false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func StripInvalidGroupForumPreset(preset string) string {
|
func StripInvalidGroupForumPreset(preset string) string {
|
||||||
|
@ -457,9 +149,8 @@ func StripInvalidPreset(preset string) string {
|
||||||
switch preset {
|
switch preset {
|
||||||
case "all", "announce", "members", "staff", "admins", "archive", "custom":
|
case "all", "announce", "members", "staff", "admins", "archive", "custom":
|
||||||
return preset
|
return preset
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move this into the phrase system?
|
// TODO: Move this into the phrase system?
|
||||||
|
|
|
@ -101,7 +101,7 @@ func forumUserCheck(w http.ResponseWriter, r *http.Request, user *User, fid int)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Put this on the user instance? Do we really want forum specific logic in there? Maybe, a method which spits a new pointer with the same contents as user?
|
// TODO: Put this on the user instance? Do we really want forum specific logic in there? Maybe, a method which spits a new pointer with the same contents as user?
|
||||||
func cascadeForumPerms(fperms ForumPerms, user *User) {
|
func cascadeForumPerms(fperms *ForumPerms, user *User) {
|
||||||
if fperms.Overrides && !user.IsSuperAdmin {
|
if fperms.Overrides && !user.IsSuperAdmin {
|
||||||
user.Perms.ViewTopic = fperms.ViewTopic
|
user.Perms.ViewTopic = fperms.ViewTopic
|
||||||
user.Perms.LikeItem = fperms.LikeItem
|
user.Perms.LikeItem = fperms.LikeItem
|
||||||
|
|
|
@ -51,7 +51,6 @@ type Stmts struct {
|
||||||
updatePlugin *sql.Stmt
|
updatePlugin *sql.Stmt
|
||||||
updatePluginInstall *sql.Stmt
|
updatePluginInstall *sql.Stmt
|
||||||
updateTheme *sql.Stmt
|
updateTheme *sql.Stmt
|
||||||
updateForum *sql.Stmt
|
|
||||||
updateUser *sql.Stmt
|
updateUser *sql.Stmt
|
||||||
updateGroupPerms *sql.Stmt
|
updateGroupPerms *sql.Stmt
|
||||||
updateGroup *sql.Stmt
|
updateGroup *sql.Stmt
|
||||||
|
@ -380,13 +379,6 @@ func _gen_mssql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateForum statement.")
|
|
||||||
stmts.updateForum, err = db.Prepare("UPDATE [forums] SET [name] = ?,[desc] = ?,[active] = ?,[preset] = ? WHERE [fid] = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Bad Query: ","UPDATE [forums] SET [name] = ?,[desc] = ?,[active] = ?,[preset] = ? WHERE [fid] = ?")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateUser statement.")
|
log.Print("Preparing updateUser statement.")
|
||||||
stmts.updateUser, err = db.Prepare("UPDATE [users] SET [name] = ?,[email] = ?,[group] = ? WHERE [uid] = ?")
|
stmts.updateUser, err = db.Prepare("UPDATE [users] SET [name] = ?,[email] = ?,[group] = ? WHERE [uid] = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -53,7 +53,6 @@ type Stmts struct {
|
||||||
updatePlugin *sql.Stmt
|
updatePlugin *sql.Stmt
|
||||||
updatePluginInstall *sql.Stmt
|
updatePluginInstall *sql.Stmt
|
||||||
updateTheme *sql.Stmt
|
updateTheme *sql.Stmt
|
||||||
updateForum *sql.Stmt
|
|
||||||
updateUser *sql.Stmt
|
updateUser *sql.Stmt
|
||||||
updateGroupPerms *sql.Stmt
|
updateGroupPerms *sql.Stmt
|
||||||
updateGroup *sql.Stmt
|
updateGroup *sql.Stmt
|
||||||
|
@ -340,12 +339,6 @@ func _gen_mysql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateForum statement.")
|
|
||||||
stmts.updateForum, err = db.Prepare("UPDATE `forums` SET `name` = ?,`desc` = ?,`active` = ?,`preset` = ? WHERE `fid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateUser statement.")
|
log.Print("Preparing updateUser statement.")
|
||||||
stmts.updateUser, err = db.Prepare("UPDATE `users` SET `name` = ?,`email` = ?,`group` = ? WHERE `uid` = ?")
|
stmts.updateUser, err = db.Prepare("UPDATE `users` SET `name` = ?,`email` = ?,`group` = ? WHERE `uid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -15,7 +15,6 @@ type Stmts struct {
|
||||||
updatePlugin *sql.Stmt
|
updatePlugin *sql.Stmt
|
||||||
updatePluginInstall *sql.Stmt
|
updatePluginInstall *sql.Stmt
|
||||||
updateTheme *sql.Stmt
|
updateTheme *sql.Stmt
|
||||||
updateForum *sql.Stmt
|
|
||||||
updateUser *sql.Stmt
|
updateUser *sql.Stmt
|
||||||
updateGroupPerms *sql.Stmt
|
updateGroupPerms *sql.Stmt
|
||||||
updateGroup *sql.Stmt
|
updateGroup *sql.Stmt
|
||||||
|
@ -80,12 +79,6 @@ func _gen_pgsql() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Preparing updateForum statement.")
|
|
||||||
stmts.updateForum, err = db.Prepare("UPDATE `forums` SET `name` = ?,`desc` = ?,`active` = ?,`preset` = ? WHERE `fid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing updateUser statement.")
|
log.Print("Preparing updateUser statement.")
|
||||||
stmts.updateUser, err = db.Prepare("UPDATE `users` SET `name` = ?,`email` = ?,`group` = ? WHERE `uid` = ?")
|
stmts.updateUser, err = db.Prepare("UPDATE `users` SET `name` = ?,`email` = ?,`group` = ? WHERE `uid` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -50,6 +50,17 @@ func (ins *MysqlInstaller) DefaultPort() string {
|
||||||
return "3306"
|
return "3306"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ins *MysqlInstaller) dbExists(dbName string) (bool, error) {
|
||||||
|
var waste string
|
||||||
|
err := ins.db.QueryRow("SHOW DATABASES LIKE '" + dbName + "'").Scan(&waste)
|
||||||
|
if err != nil && err != sql.ErrNoRows {
|
||||||
|
return false, err
|
||||||
|
} else if err == sql.ErrNoRows {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ins *MysqlInstaller) InitDatabase() (err error) {
|
func (ins *MysqlInstaller) InitDatabase() (err error) {
|
||||||
_dbPassword := ins.dbPassword
|
_dbPassword := ins.dbPassword
|
||||||
if _dbPassword != "" {
|
if _dbPassword != "" {
|
||||||
|
@ -67,13 +78,13 @@ func (ins *MysqlInstaller) InitDatabase() (err error) {
|
||||||
}
|
}
|
||||||
fmt.Println("Successfully connected to the database")
|
fmt.Println("Successfully connected to the database")
|
||||||
|
|
||||||
var waste string
|
ins.db = db
|
||||||
err = db.QueryRow("SHOW DATABASES LIKE '" + ins.dbName + "'").Scan(&waste)
|
ok, err := ins.dbExists(ins.dbName)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if !ok {
|
||||||
fmt.Println("Unable to find the database. Attempting to create it")
|
fmt.Println("Unable to find the database. Attempting to create it")
|
||||||
_, err = db.Exec("CREATE DATABASE IF NOT EXISTS " + ins.dbName)
|
_, err = db.Exec("CREATE DATABASE IF NOT EXISTS " + ins.dbName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -82,7 +93,7 @@ func (ins *MysqlInstaller) InitDatabase() (err error) {
|
||||||
fmt.Println("The database was successfully created")
|
fmt.Println("The database was successfully created")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Switching to database " + ins.dbName)
|
fmt.Println("Switching to database ", ins.dbName)
|
||||||
_, err = db.Exec("USE " + ins.dbName)
|
_, err = db.Exec("USE " + ins.dbName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -90,13 +101,7 @@ func (ins *MysqlInstaller) InitDatabase() (err error) {
|
||||||
|
|
||||||
// Ready the query builder
|
// Ready the query builder
|
||||||
qgen.Builder.SetConn(db)
|
qgen.Builder.SetConn(db)
|
||||||
err = qgen.Builder.SetAdapter("mysql")
|
return qgen.Builder.SetAdapter("mysql")
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ins.db = db
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ins *MysqlInstaller) TableDefs() (err error) {
|
func (ins *MysqlInstaller) TableDefs() (err error) {
|
||||||
|
@ -122,7 +127,7 @@ func (ins *MysqlInstaller) TableDefs() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Creating table '" + table + "'")
|
fmt.Printf("Creating table '%s'", table)
|
||||||
data, err := ioutil.ReadFile("./schema/mysql/" + f.Name())
|
data, err := ioutil.ReadFile("./schema/mysql/" + f.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -135,7 +140,6 @@ func (ins *MysqlInstaller) TableDefs() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//fmt.Println("Finished creating the tables")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,8 +167,6 @@ func (ins *MysqlInstaller) InitialData() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//fmt.Println("Finished inserting the database data")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,14 +69,9 @@ func (ins *PgsqlInstaller) InitDatabase() (err error) {
|
||||||
// TODO: Create the database, if it doesn't exist
|
// TODO: Create the database, if it doesn't exist
|
||||||
|
|
||||||
// Ready the query builder
|
// Ready the query builder
|
||||||
qgen.Builder.SetConn(db)
|
|
||||||
err = qgen.Builder.SetAdapter("pgsql")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ins.db = db
|
ins.db = db
|
||||||
|
qgen.Builder.SetConn(db)
|
||||||
return nil
|
return qgen.Builder.SetAdapter("pgsql")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ins *PgsqlInstaller) TableDefs() (err error) {
|
func (ins *PgsqlInstaller) TableDefs() (err error) {
|
||||||
|
|
43
misc_test.go
43
misc_test.go
|
@ -607,8 +607,8 @@ func TestForumPermsStore(t *testing.T) {
|
||||||
if !gloinited {
|
if !gloinited {
|
||||||
gloinit()
|
gloinit()
|
||||||
}
|
}
|
||||||
if !pluginsInited {
|
if !common.PluginsInited {
|
||||||
initPlugins()
|
common.InitPlugins()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,8 +617,8 @@ func TestGroupStore(t *testing.T) {
|
||||||
if !gloinited {
|
if !gloinited {
|
||||||
gloinit()
|
gloinit()
|
||||||
}
|
}
|
||||||
if !pluginsInited {
|
if !common.PluginsInited {
|
||||||
initPlugins()
|
common.InitPlugins()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := common.Gstore.Get(-1)
|
_, err := common.Gstore.Get(-1)
|
||||||
|
@ -728,8 +728,8 @@ func TestReplyStore(t *testing.T) {
|
||||||
if !gloinited {
|
if !gloinited {
|
||||||
gloinit()
|
gloinit()
|
||||||
}
|
}
|
||||||
if !pluginsInited {
|
if !common.PluginsInited {
|
||||||
initPlugins()
|
common.InitPlugins()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := common.Rstore.Get(-1)
|
_, err := common.Rstore.Get(-1)
|
||||||
|
@ -770,8 +770,8 @@ func TestProfileReplyStore(t *testing.T) {
|
||||||
if !gloinited {
|
if !gloinited {
|
||||||
gloinit()
|
gloinit()
|
||||||
}
|
}
|
||||||
if !pluginsInited {
|
if !common.PluginsInited {
|
||||||
initPlugins()
|
common.InitPlugins()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := common.Prstore.Get(-1)
|
_, err := common.Prstore.Get(-1)
|
||||||
|
@ -845,7 +845,7 @@ func TestAuth(t *testing.T) {
|
||||||
|
|
||||||
/* No extra salt tests, we might not need this extra salt, as bcrypt has it's own? */
|
/* No extra salt tests, we might not need this extra salt, as bcrypt has it's own? */
|
||||||
realPassword = "Madame Cassandra's Mystic Orb"
|
realPassword = "Madame Cassandra's Mystic Orb"
|
||||||
t.Log("Set realPassword to '" + realPassword + "'")
|
t.Logf("Set realPassword to '%s'", realPassword)
|
||||||
t.Log("Hashing the real password")
|
t.Log("Hashing the real password")
|
||||||
hashedPassword, err = common.BcryptGeneratePasswordNoSalt(realPassword)
|
hashedPassword, err = common.BcryptGeneratePasswordNoSalt(realPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -853,34 +853,31 @@ func TestAuth(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
password = realPassword
|
password = realPassword
|
||||||
t.Log("Testing password '" + password + "'")
|
t.Logf("Testing password '%s'", password)
|
||||||
t.Log("Testing salt '" + salt + "'")
|
t.Logf("Testing salt '%s'", salt)
|
||||||
err = common.CheckPassword(hashedPassword, password, salt)
|
err = common.CheckPassword(hashedPassword, password, salt)
|
||||||
if err == ErrMismatchedHashAndPassword {
|
if err == common.ErrMismatchedHashAndPassword {
|
||||||
t.Error("The two don't match")
|
t.Error("The two don't match")
|
||||||
} else if err == ErrPasswordTooLong {
|
} else if err == common.ErrPasswordTooLong {
|
||||||
t.Error("CheckPassword thinks the password is too long")
|
t.Error("CheckPassword thinks the password is too long")
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
password = "hahaha"
|
password = "hahaha"
|
||||||
t.Log("Testing password '" + password + "'")
|
t.Logf("Testing password '%s'", password)
|
||||||
t.Log("Testing salt '" + salt + "'")
|
t.Logf("Testing salt '%s'", salt)
|
||||||
err = common.CheckPassword(hashedPassword, password, salt)
|
err = common.CheckPassword(hashedPassword, password, salt)
|
||||||
if err == ErrPasswordTooLong {
|
if err == common.ErrPasswordTooLong {
|
||||||
t.Error("CheckPassword thinks the password is too long")
|
t.Error("CheckPassword thinks the password is too long")
|
||||||
} else if err == nil {
|
} else if err == nil {
|
||||||
t.Error("The two shouldn't match!")
|
t.Error("The two shouldn't match!")
|
||||||
}
|
}
|
||||||
|
|
||||||
password = "Madame Cassandra's Mystic"
|
password = "Madame Cassandra's Mystic"
|
||||||
t.Log("Testing password '" + password + "'")
|
t.Logf("Testing password '%s'", password)
|
||||||
t.Log("Testing salt '" + salt + "'")
|
t.Logf("Testing salt '%s'", salt)
|
||||||
err = common.CheckPassword(hashedPassword, password, salt)
|
err = common.CheckPassword(hashedPassword, password, salt)
|
||||||
if err == ErrPasswordTooLong {
|
expect(t, err != common.ErrPasswordTooLong, "CheckPassword thinks the password is too long")
|
||||||
t.Error("CheckPassword thinks the password is too long")
|
expect(t, err != nil, "The two shouldn't match!")
|
||||||
} else if err == nil {
|
|
||||||
t.Error("The two shouldn't match!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -425,9 +425,6 @@ func routePanelForumsEditPermsSubmit(w http.ResponseWriter, r *http.Request, use
|
||||||
return common.LocalErrorJSQ("Invalid Group ID", w, r, user, isJs)
|
return common.LocalErrorJSQ("Invalid Group ID", w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
permPreset := common.StripInvalidGroupForumPreset(r.PostFormValue("perm_preset"))
|
|
||||||
fperms, changed := common.GroupForumPresetToForumPerms(permPreset)
|
|
||||||
|
|
||||||
forum, err := common.Fstore.Get(fid)
|
forum, err := common.Fstore.Get(fid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return common.LocalErrorJSQ("This forum doesn't exist", w, r, user, isJs)
|
return common.LocalErrorJSQ("This forum doesn't exist", w, r, user, isJs)
|
||||||
|
@ -435,33 +432,10 @@ func routePanelForumsEditPermsSubmit(w http.ResponseWriter, r *http.Request, use
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return common.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ! IMPORTANT
|
permPreset := common.StripInvalidGroupForumPreset(r.PostFormValue("perm_preset"))
|
||||||
// TODO: Refactor this
|
err = forum.SetPreset(permPreset, gid)
|
||||||
common.ForumUpdateMutex.Lock()
|
|
||||||
defer common.ForumUpdateMutex.Unlock()
|
|
||||||
if changed {
|
|
||||||
common.PermUpdateMutex.Lock()
|
|
||||||
defer common.PermUpdateMutex.Unlock()
|
|
||||||
group, err := common.Gstore.Get(gid)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError("The group whose permissions you're updating doesn't exist.", w, r, user)
|
return common.LocalErrorJSQ(err.Error(), w, r, user, isJs)
|
||||||
}
|
|
||||||
group.Forums[fid] = fperms
|
|
||||||
|
|
||||||
err = common.ReplaceForumPermsForGroup(gid, map[int]string{fid: permPreset}, map[int]common.ForumPerms{fid: fperms})
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Add this and replaceForumPermsForGroup into a transaction?
|
|
||||||
_, err = stmts.updateForum.Exec(forum.Name, forum.Desc, forum.Active, "", fid)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
|
||||||
}
|
|
||||||
err = common.Fstore.Reload(fid)
|
|
||||||
if err != nil {
|
|
||||||
return common.LocalErrorJSQ("Unable to reload forum", w, r, user, isJs)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isJs {
|
if !isJs {
|
||||||
|
|
|
@ -181,15 +181,16 @@ func processWhere(wherestr string) (where []DBWhere) {
|
||||||
segment += ")"
|
segment += ")"
|
||||||
for i := 0; i < len(segment); i++ {
|
for i := 0; i < len(segment); i++ {
|
||||||
char := segment[i]
|
char := segment[i]
|
||||||
if '0' <= char && char <= '9' {
|
switch {
|
||||||
|
case '0' <= char && char <= '9':
|
||||||
i = tmpWhere.parseNumber(segment, i)
|
i = tmpWhere.parseNumber(segment, i)
|
||||||
} else if ('a' <= char && char <= 'z') || ('A' <= char && char <= 'Z') || char == '_' {
|
case ('a' <= char && char <= 'z') || ('A' <= char && char <= 'Z') || char == '_':
|
||||||
i = tmpWhere.parseColumn(segment, i)
|
i = tmpWhere.parseColumn(segment, i)
|
||||||
} else if char == '\'' {
|
case char == '\'':
|
||||||
i = tmpWhere.parseString(segment, i)
|
i = tmpWhere.parseString(segment, i)
|
||||||
} else if isOpByte(char) {
|
case isOpByte(char):
|
||||||
i = tmpWhere.parseOperator(segment, i)
|
i = tmpWhere.parseOperator(segment, i)
|
||||||
} else if char == '?' {
|
case char == '?':
|
||||||
tmpWhere.Expr = append(tmpWhere.Expr, DBToken{"?", "substitute"})
|
tmpWhere.Expr = append(tmpWhere.Expr, DBToken{"?", "substitute"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,11 +217,12 @@ func (setter *DBSetter) parseColumn(segment string, i int) int {
|
||||||
var buffer string
|
var buffer string
|
||||||
for ; i < len(segment); i++ {
|
for ; i < len(segment); i++ {
|
||||||
char := segment[i]
|
char := segment[i]
|
||||||
if ('a' <= char && char <= 'z') || ('A' <= char && char <= 'Z') || char == '_' {
|
switch {
|
||||||
|
case ('a' <= char && char <= 'z') || ('A' <= char && char <= 'Z') || char == '_':
|
||||||
buffer += string(char)
|
buffer += string(char)
|
||||||
} else if char == '(' {
|
case char == '(':
|
||||||
return setter.parseFunction(segment, buffer, i)
|
return setter.parseFunction(segment, buffer, i)
|
||||||
} else {
|
default:
|
||||||
i--
|
i--
|
||||||
setter.Expr = append(setter.Expr, DBToken{buffer, "column"})
|
setter.Expr = append(setter.Expr, DBToken{buffer, "column"})
|
||||||
return i
|
return i
|
||||||
|
@ -303,15 +305,16 @@ func processSet(setstr string) (setter []DBSetter) {
|
||||||
|
|
||||||
for i := 0; i < len(segment); i++ {
|
for i := 0; i < len(segment); i++ {
|
||||||
char := segment[i]
|
char := segment[i]
|
||||||
if '0' <= char && char <= '9' {
|
switch {
|
||||||
|
case '0' <= char && char <= '9':
|
||||||
i = tmpSetter.parseNumber(segment, i)
|
i = tmpSetter.parseNumber(segment, i)
|
||||||
} else if ('a' <= char && char <= 'z') || ('A' <= char && char <= 'Z') || char == '_' {
|
case ('a' <= char && char <= 'z') || ('A' <= char && char <= 'Z') || char == '_':
|
||||||
i = tmpSetter.parseColumn(segment, i)
|
i = tmpSetter.parseColumn(segment, i)
|
||||||
} else if char == '\'' {
|
case char == '\'':
|
||||||
i = tmpSetter.parseString(segment, i)
|
i = tmpSetter.parseString(segment, i)
|
||||||
} else if isOpByte(char) {
|
case isOpByte(char):
|
||||||
i = tmpSetter.parseOperator(segment, i)
|
i = tmpSetter.parseOperator(segment, i)
|
||||||
} else if char == '?' {
|
case char == '?':
|
||||||
tmpSetter.Expr = append(tmpSetter.Expr, DBToken{"?", "substitute"})
|
tmpSetter.Expr = append(tmpSetter.Expr, DBToken{"?", "substitute"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -352,8 +352,6 @@ func writeUpdates(adapter qgen.Adapter) error {
|
||||||
|
|
||||||
build.Update("updateTheme").Table("themes").Set("default = ?").Where("uname = ?").Parse()
|
build.Update("updateTheme").Table("themes").Set("default = ?").Where("uname = ?").Parse()
|
||||||
|
|
||||||
build.Update("updateForum").Table("forums").Set("name = ?, desc = ?, active = ?, preset = ?").Where("fid = ?").Parse()
|
|
||||||
|
|
||||||
build.Update("updateUser").Table("users").Set("name = ?, email = ?, group = ?").Where("uid = ?").Parse()
|
build.Update("updateUser").Table("users").Set("name = ?, email = ?, group = ?").Where("uid = ?").Parse()
|
||||||
|
|
||||||
build.Update("updateGroupPerms").Table("users_groups").Set("permissions = ?").Where("gid = ?").Parse()
|
build.Update("updateGroupPerms").Table("users_groups").Set("permissions = ?").Where("gid = ?").Parse()
|
||||||
|
|
|
@ -849,13 +849,12 @@ func routeRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.Use
|
||||||
}
|
}
|
||||||
|
|
||||||
password := r.PostFormValue("password")
|
password := r.PostFormValue("password")
|
||||||
if password == "" {
|
switch password {
|
||||||
|
case "":
|
||||||
return common.LocalError("You didn't put in a password.", w, r, user)
|
return common.LocalError("You didn't put in a password.", w, r, user)
|
||||||
}
|
case username:
|
||||||
if password == username {
|
|
||||||
return common.LocalError("You can't use your username as your password.", w, r, user)
|
return common.LocalError("You can't use your username as your password.", w, r, user)
|
||||||
}
|
case email:
|
||||||
if password == email {
|
|
||||||
return common.LocalError("You can't use your email as your password.", w, r, user)
|
return common.LocalError("You can't use your email as your password.", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ ul {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rowblock {
|
.rowblock, .colstack_item {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
border: 1px solid var(--header-border-color);
|
border: 1px solid var(--header-border-color);
|
||||||
border-bottom: 2px solid var(--header-border-color);
|
border-bottom: 2px solid var(--header-border-color);
|
||||||
|
|
Loading…
Reference in New Issue