2017-11-13 05:22:37 +00:00
|
|
|
package common
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"encoding/json"
|
|
|
|
|
2018-10-27 03:21:02 +00:00
|
|
|
"github.com/Azareal/Gosora/query_gen"
|
2017-11-13 05:22:37 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// ? - 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",
|
2018-01-15 08:24:18 +00:00
|
|
|
"MoveTopic",
|
2017-11-13 05:22:37 +00:00
|
|
|
}
|
|
|
|
|
2017-11-23 05:37:08 +00:00
|
|
|
// TODO: Rename this to ForumPermSet?
|
2017-11-13 05:22:37 +00:00
|
|
|
/* 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
|
2018-01-15 08:24:18 +00:00
|
|
|
MoveTopic bool
|
2017-11-13 05:22:37 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2017-12-25 02:41:10 +00:00
|
|
|
// TODO: The group ID is probably a variable somewhere. Find it and use it.
|
|
|
|
// Group 5 is the Awaiting Activation group
|
|
|
|
err = ReplaceForumPermsForGroupTx(tx, 5, map[int]string{fid: ""}, map[int]*ForumPerms{fid: permmap["guests"]})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Consult a config setting instead of GuestUser?
|
|
|
|
err = ReplaceForumPermsForGroupTx(tx, GuestUser.Group, map[int]string{fid: ""}, map[int]*ForumPerms{fid: permmap["guests"]})
|
2017-11-13 05:22:37 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = tx.Commit()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-06-24 13:49:29 +00:00
|
|
|
err = FPStore.Reload(fid)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return TopicList.RebuildPermTree()
|
2017-11-13 05:22:37 +00:00
|
|
|
}
|
|
|
|
|
2018-06-24 13:49:29 +00:00
|
|
|
// TODO: FPStore.Reload?
|
2017-11-13 05:22:37 +00:00
|
|
|
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()
|
2018-06-24 13:49:29 +00:00
|
|
|
|
2017-11-13 05:22:37 +00:00
|
|
|
err = ReplaceForumPermsForGroupTx(tx, gid, presetSet, permSets)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-06-24 13:49:29 +00:00
|
|
|
err = tx.Commit()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return TopicList.RebuildPermTree()
|
2017-11-13 05:22:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2018-01-10 03:32:48 +00:00
|
|
|
// TODO: We really need to improve the thread safety of this
|
2017-11-13 05:22:37 +00:00
|
|
|
func ForumPermsToGroupForumPreset(fperms *ForumPerms) string {
|
|
|
|
if !fperms.Overrides {
|
|
|
|
return "default"
|
|
|
|
}
|
|
|
|
if !fperms.ViewTopic {
|
|
|
|
return "no_access"
|
|
|
|
}
|
|
|
|
var canPost = (fperms.LikeItem && fperms.CreateTopic && fperms.CreateReply)
|
2018-01-15 08:24:18 +00:00
|
|
|
var canModerate = (canPost && fperms.EditTopic && fperms.DeleteTopic && fperms.EditReply && fperms.DeleteReply && fperms.PinTopic && fperms.CloseTopic && fperms.MoveTopic)
|
2017-11-13 05:22:37 +00:00
|
|
|
if canModerate {
|
|
|
|
return "can_moderate"
|
|
|
|
}
|
2018-01-15 08:24:18 +00:00
|
|
|
if fperms.EditTopic || fperms.DeleteTopic || fperms.EditReply || fperms.DeleteReply || fperms.PinTopic || fperms.CloseTopic || fperms.MoveTopic {
|
2017-11-13 05:22:37 +00:00
|
|
|
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,
|
2018-01-15 08:24:18 +00:00
|
|
|
MoveTopic: true,
|
2017-11-13 05:22:37 +00:00
|
|
|
|
|
|
|
Overrides: true,
|
|
|
|
ExtData: make(map[string]bool),
|
|
|
|
}
|
|
|
|
}
|