6bae378db0
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.
193 lines
4.5 KiB
Go
193 lines
4.5 KiB
Go
package common
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/json"
|
|
"log"
|
|
|
|
"../query_gen/lib"
|
|
)
|
|
|
|
var Fpstore ForumPermsStore
|
|
|
|
type ForumPermsStore interface {
|
|
Init() error
|
|
Get(fid int, gid int) (fperms ForumPerms, err error)
|
|
Reload(id int) error
|
|
}
|
|
|
|
type ForumPermsCache interface {
|
|
}
|
|
|
|
type MemoryForumPermsStore struct {
|
|
get *sql.Stmt
|
|
getByForum *sql.Stmt
|
|
}
|
|
|
|
func NewMemoryForumPermsStore() (*MemoryForumPermsStore, error) {
|
|
acc := qgen.Builder.Accumulator()
|
|
return &MemoryForumPermsStore{
|
|
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 {
|
|
fids, err := Fstore.GetAllIDs()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if Dev.SuperDebug {
|
|
log.Print("fids: ", fids)
|
|
}
|
|
|
|
rows, err := fps.get.Query()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer rows.Close()
|
|
|
|
if Dev.DebugMode {
|
|
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
|
|
forumPerms = make(map[int]map[int]ForumPerms)
|
|
for rows.Next() {
|
|
var gid, fid int
|
|
var perms []byte
|
|
var pperms ForumPerms
|
|
err = rows.Scan(&gid, &fid, &perms)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if Dev.SuperDebug {
|
|
log.Print("perms: ", string(perms))
|
|
}
|
|
err = json.Unmarshal(perms, &pperms)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
pperms.ExtData = make(map[string]bool)
|
|
pperms.Overrides = true
|
|
_, ok := forumPerms[gid]
|
|
if !ok {
|
|
forumPerms[gid] = make(map[int]ForumPerms)
|
|
}
|
|
|
|
if Dev.SuperDebug {
|
|
log.Print("gid: ", gid)
|
|
log.Print("fid: ", fid)
|
|
log.Printf("perms: %+v\n", pperms)
|
|
}
|
|
forumPerms[gid][fid] = pperms
|
|
}
|
|
|
|
return fps.cascadePermSetToGroups(forumPerms, fids)
|
|
}
|
|
|
|
// TODO: Need a more thread-safe way of doing this. Possibly with sync.Map?
|
|
func (fps *MemoryForumPermsStore) Reload(fid int) error {
|
|
if Dev.DebugMode {
|
|
log.Printf("Reloading the forum permissions for forum #%d", fid)
|
|
}
|
|
fids, err := Fstore.GetAllIDs()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
rows, err := fps.getByForum.Query(fid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer rows.Close()
|
|
|
|
for rows.Next() {
|
|
var gid int
|
|
var perms []byte
|
|
var pperms ForumPerms
|
|
err := rows.Scan(&gid, &perms)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = json.Unmarshal(perms, &pperms)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
pperms.ExtData = make(map[string]bool)
|
|
pperms.Overrides = true
|
|
_, ok := forumPerms[gid]
|
|
if !ok {
|
|
forumPerms[gid] = make(map[int]ForumPerms)
|
|
}
|
|
forumPerms[gid][fid] = pperms
|
|
}
|
|
|
|
return fps.cascadePermSetToGroups(forumPerms, fids)
|
|
}
|
|
|
|
func (fps *MemoryForumPermsStore) cascadePermSetToGroups(forumPerms map[int]map[int]ForumPerms, fids []int) error {
|
|
groups, err := Gstore.GetAll()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, group := range groups {
|
|
if Dev.DebugMode {
|
|
log.Printf("Updating the forum permissions for Group #%d", group.ID)
|
|
}
|
|
group.Forums = []ForumPerms{BlankForumPerms}
|
|
group.CanSee = []int{}
|
|
fps.cascadePermSetToGroup(forumPerms, group, fids)
|
|
|
|
if Dev.SuperDebug {
|
|
log.Printf("group.CanSee (length %d): %+v \n", len(group.CanSee), group.CanSee)
|
|
log.Printf("group.Forums (length %d): %+v\n", len(group.Forums), group.Forums)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[int]ForumPerms, group *Group, fids []int) {
|
|
for _, fid := range fids {
|
|
if Dev.SuperDebug {
|
|
log.Printf("Forum #%+v\n", fid)
|
|
}
|
|
forumPerm, ok := forumPerms[group.ID][fid]
|
|
if ok {
|
|
//log.Printf("Overriding permissions for forum #%d",fid)
|
|
group.Forums = append(group.Forums, forumPerm)
|
|
} else {
|
|
//log.Printf("Inheriting from group defaults for forum #%d",fid)
|
|
forumPerm = BlankForumPerms
|
|
group.Forums = append(group.Forums, forumPerm)
|
|
}
|
|
if forumPerm.Overrides {
|
|
if forumPerm.ViewTopic {
|
|
group.CanSee = append(group.CanSee, fid)
|
|
}
|
|
} else if group.Perms.ViewTopic {
|
|
group.CanSee = append(group.CanSee, fid)
|
|
}
|
|
|
|
if Dev.SuperDebug {
|
|
log.Print("group.ID: ", group.ID)
|
|
log.Printf("forumPerm: %+v\n", forumPerm)
|
|
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
|
|
group, err := Gstore.Get(gid)
|
|
if err != nil {
|
|
return fperms, ErrNoRows
|
|
}
|
|
return group.Forums[fid], nil
|
|
}
|