Users can now delete their own posts.
Merge GlobalPerms and LocalPerms phrase spaces into Perms. Shorten more things and eliminate boilerplate.
This commit is contained in:
parent
45a3065db1
commit
a5f77c376b
|
@ -25,12 +25,12 @@ func main() {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
log.Println("Running the query generator")
|
log.Println("Running the query generator")
|
||||||
for _, adapter := range qgen.Registry {
|
for _, a := range qgen.Registry {
|
||||||
log.Printf("Building the queries for the %s adapter", adapter.GetName())
|
log.Printf("Building the queries for the %s adapter", a.GetName())
|
||||||
qgen.Install.SetAdapterInstance(adapter)
|
qgen.Install.SetAdapterInstance(a)
|
||||||
qgen.Install.AddPlugins(NewPrimaryKeySpitter()) // TODO: Do we really need to fill the spitter for every adapter?
|
qgen.Install.AddPlugins(NewPrimaryKeySpitter()) // TODO: Do we really need to fill the spitter for every adapter?
|
||||||
|
|
||||||
err := writeStatements(adapter)
|
err := writeStatements(a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
err = adapter.Write()
|
err = a.Write()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
|
@ -46,73 +46,31 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func writeStatements(adapter qgen.Adapter) error {
|
func writeStatements(a qgen.Adapter) (err error) {
|
||||||
err := createTables(adapter)
|
e := func(f func(qgen.Adapter) error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
err = f(a)
|
||||||
err = seedTables(adapter)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
e(createTables)
|
||||||
err = writeSelects(adapter)
|
e(seedTables)
|
||||||
if err != nil {
|
e(writeSelects)
|
||||||
|
e(writeLeftJoins)
|
||||||
|
e(writeInnerJoins)
|
||||||
|
e(writeInserts)
|
||||||
|
e(writeUpdates)
|
||||||
|
e(writeDeletes)
|
||||||
|
e(writeSimpleCounts)
|
||||||
|
e(writeInsertSelects)
|
||||||
|
e(writeInsertLeftJoins)
|
||||||
|
e(writeInsertInnerJoins)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = writeLeftJoins(adapter)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = writeInnerJoins(adapter)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = writeInserts(adapter)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = writeUpdates(adapter)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = writeDeletes(adapter)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = writeSimpleCounts(adapter)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = writeInsertSelects(adapter)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = writeInsertLeftJoins(adapter)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = writeInsertInnerJoins(adapter)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type si = map[string]interface{}
|
type si = map[string]interface{}
|
||||||
|
|
||||||
func seedTables(adapter qgen.Adapter) error {
|
func seedTables(a qgen.Adapter) error {
|
||||||
qgen.Install.AddIndex("topics", "parentID", "parentID")
|
qgen.Install.AddIndex("topics", "parentID", "parentID")
|
||||||
qgen.Install.AddIndex("replies", "tid", "tid")
|
qgen.Install.AddIndex("replies", "tid", "tid")
|
||||||
qgen.Install.AddIndex("polls", "parentID", "parentID")
|
qgen.Install.AddIndex("polls", "parentID", "parentID")
|
||||||
|
|
|
@ -43,8 +43,7 @@ type LanguagePack struct {
|
||||||
|
|
||||||
// Should we use a sync map or a struct for these? It would be nice, if we could keep all the phrases consistent.
|
// Should we use a sync map or a struct for these? It would be nice, if we could keep all the phrases consistent.
|
||||||
Levels LevelPhrases
|
Levels LevelPhrases
|
||||||
GlobalPerms map[string]string
|
Perms map[string]string
|
||||||
LocalPerms map[string]string
|
|
||||||
SettingPhrases map[string]string
|
SettingPhrases map[string]string
|
||||||
PermPresets map[string]string
|
PermPresets map[string]string
|
||||||
Accounts map[string]string // TODO: Apply these phrases in the software proper
|
Accounts map[string]string // TODO: Apply these phrases in the software proper
|
||||||
|
@ -184,16 +183,8 @@ func GetLevelPhrase(level int) string {
|
||||||
return strings.Replace(levelPhrases.Level, "{0}", strconv.Itoa(level), -1)
|
return strings.Replace(levelPhrases.Level, "{0}", strconv.Itoa(level), -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Merge these two maps?
|
func GetPermPhrase(name string) string {
|
||||||
func GetGlobalPermPhrase(name string) string {
|
res, ok := currentLangPack.Load().(*LanguagePack).Perms[name]
|
||||||
res, ok := currentLangPack.Load().(*LanguagePack).GlobalPerms[name]
|
|
||||||
if !ok {
|
|
||||||
return getPlaceholder("perms", name)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
func GetLocalPermPhrase(name string) string {
|
|
||||||
res, ok := currentLangPack.Load().(*LanguagePack).LocalPerms[name]
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return getPlaceholder("perms", name)
|
return getPlaceholder("perms", name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"html"
|
"html"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
qgen "github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ReplyUser struct {
|
type ReplyUser struct {
|
||||||
|
@ -45,6 +45,7 @@ type ReplyUser struct {
|
||||||
ActionIcon string
|
ActionIcon string
|
||||||
|
|
||||||
Attachments []*MiniAttachment
|
Attachments []*MiniAttachment
|
||||||
|
Deletable bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Reply struct {
|
type Reply struct {
|
||||||
|
|
|
@ -238,7 +238,7 @@ func compileCommons(c *tmpl.CTemplateSet, header *Header, header2 *Header, forum
|
||||||
}, VoteCount: 7}
|
}, VoteCount: 7}
|
||||||
avatar, microAvatar := BuildAvatar(62, "")
|
avatar, microAvatar := BuildAvatar(62, "")
|
||||||
miniAttach := []*MiniAttachment{&MiniAttachment{Path: "/"}}
|
miniAttach := []*MiniAttachment{&MiniAttachment{Path: "/"}}
|
||||||
topic := TopicUser{1, "blah", "Blah", "Hey there!", 0, false, false, now, now, 1, 1, 0, "", "127.0.0.1", 1, 0, 1, 0, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", "", "", 58, false, miniAttach, nil}
|
topic := TopicUser{1, "blah", "Blah", "Hey there!", 0, false, false, now, now, 1, 1, 0, "", "127.0.0.1", 1, 0, 1, 0, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", "", "", 58, false, miniAttach, nil,false}
|
||||||
|
|
||||||
var replyList []*ReplyUser
|
var replyList []*ReplyUser
|
||||||
reply := Reply{1, 1, "Yo!", 1, Config.DefaultGroup, now, 0, 0, 1, "::1", true, 1, 1, ""}
|
reply := Reply{1, 1, "Yo!", 1, Config.DefaultGroup, now, 0, 0, 1, "::1", true, 1, 1, ""}
|
||||||
|
@ -520,7 +520,7 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
|
||||||
}, VoteCount: 7}
|
}, VoteCount: 7}
|
||||||
avatar, microAvatar := BuildAvatar(62, "")
|
avatar, microAvatar := BuildAvatar(62, "")
|
||||||
miniAttach := []*MiniAttachment{&MiniAttachment{Path: "/"}}
|
miniAttach := []*MiniAttachment{&MiniAttachment{Path: "/"}}
|
||||||
topic := TopicUser{1, "blah", "Blah", "Hey there!", 62, false, false, now, now, 1, 1, 0, "", "127.0.0.1", 1, 0, 1, 0, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", "", "", 58, false, miniAttach, nil}
|
topic := TopicUser{1, "blah", "Blah", "Hey there!", 62, false, false, now, now, 1, 1, 0, "", "127.0.0.1", 1, 0, 1, 0, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", "", "", 58, false, miniAttach, nil,false}
|
||||||
var replyList []*ReplyUser
|
var replyList []*ReplyUser
|
||||||
// TODO: Do we really want the UID here to be zero?
|
// TODO: Do we really want the UID here to be zero?
|
||||||
avatar, microAvatar = BuildAvatar(0, "")
|
avatar, microAvatar = BuildAvatar(0, "")
|
||||||
|
|
|
@ -10,13 +10,14 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"html"
|
"html"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
|
||||||
//"log"
|
//"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
p "github.com/Azareal/Gosora/common/phrases"
|
p "github.com/Azareal/Gosora/common/phrases"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
qgen "github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is also in reply.go
|
// This is also in reply.go
|
||||||
|
@ -89,6 +90,7 @@ type TopicUser struct {
|
||||||
|
|
||||||
Attachments []*MiniAttachment
|
Attachments []*MiniAttachment
|
||||||
Rids []int
|
Rids []int
|
||||||
|
Deletable bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Embed TopicUser to simplify this structure and it's related logic?
|
// TODO: Embed TopicUser to simplify this structure and it's related logic?
|
||||||
|
@ -427,6 +429,7 @@ var lockai = "🔒"+aipost
|
||||||
var unlockai = "🔓"
|
var unlockai = "🔓"
|
||||||
var stickai = "📌"
|
var stickai = "📌"
|
||||||
var unstickai = "📌" + aipost
|
var unstickai = "📌" + aipost
|
||||||
|
|
||||||
func (ru *ReplyUser) Init() error {
|
func (ru *ReplyUser) Init() error {
|
||||||
ru.UserLink = BuildProfileURL(NameToSlug(ru.CreatedByName), ru.CreatedBy)
|
ru.UserLink = BuildProfileURL(NameToSlug(ru.CreatedByName), ru.CreatedBy)
|
||||||
ru.ContentLines = strings.Count(ru.Content, "\n")
|
ru.ContentLines = strings.Count(ru.Content, "\n")
|
||||||
|
@ -545,6 +548,7 @@ func (t *TopicUser) Replies(offset int, pFrag int, user *User) (rlist []*ReplyUs
|
||||||
attachMap[reply.ID] = len(rlist)
|
attachMap[reply.ID] = len(rlist)
|
||||||
attachQueryList = append(attachQueryList, reply.ID)
|
attachQueryList = append(attachQueryList, reply.ID)
|
||||||
}
|
}
|
||||||
|
reply.Deletable = user.Perms.DeleteReply || reply.CreatedBy == user.ID
|
||||||
|
|
||||||
hTbl.VhookNoRet("topic_reply_row_assign", &rlist, &reply)
|
hTbl.VhookNoRet("topic_reply_row_assign", &rlist, &reply)
|
||||||
rlist = append(rlist, reply)
|
rlist = append(rlist, reply)
|
||||||
|
@ -568,6 +572,7 @@ func (t *TopicUser) Replies(offset int, pFrag int, user *User) (rlist []*ReplyUs
|
||||||
}
|
}
|
||||||
reply.ContentHtml = ParseMessage(reply.Content, t.ParentID, "forums")
|
reply.ContentHtml = ParseMessage(reply.Content, t.ParentID, "forums")
|
||||||
|
|
||||||
|
// TODO: This doesn't work properly so pick the first one instead?
|
||||||
if reply.ID == pFrag {
|
if reply.ID == pFrag {
|
||||||
ogdesc = reply.Content
|
ogdesc = reply.Content
|
||||||
if len(ogdesc) > 200 {
|
if len(ogdesc) > 200 {
|
||||||
|
@ -583,6 +588,7 @@ func (t *TopicUser) Replies(offset int, pFrag int, user *User) (rlist []*ReplyUs
|
||||||
attachMap[reply.ID] = len(rlist)
|
attachMap[reply.ID] = len(rlist)
|
||||||
attachQueryList = append(attachQueryList, reply.ID)
|
attachQueryList = append(attachQueryList, reply.ID)
|
||||||
}
|
}
|
||||||
|
reply.Deletable = user.Perms.DeleteReply || reply.CreatedBy == user.ID
|
||||||
|
|
||||||
hTbl.VhookNoRet("topic_reply_row_assign", &rlist, &reply)
|
hTbl.VhookNoRet("topic_reply_row_assign", &rlist, &reply)
|
||||||
// TODO: Use a pointer instead to make it easier to abstract this loop? What impact would this have on escape analysis?
|
// TODO: Use a pointer instead to make it easier to abstract this loop? What impact would this have on escape analysis?
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
"LevelMax": ""
|
"LevelMax": ""
|
||||||
},
|
},
|
||||||
|
|
||||||
"GlobalPerms": {
|
"Perms": {
|
||||||
"BanUsers": "Can ban users",
|
"BanUsers": "Can ban users",
|
||||||
"ActivateUsers": "Can activate users",
|
"ActivateUsers": "Can activate users",
|
||||||
"EditUser": "Can edit users",
|
"EditUser": "Can edit users",
|
||||||
|
@ -30,10 +30,8 @@
|
||||||
|
|
||||||
"UploadFiles": "Can upload files",
|
"UploadFiles": "Can upload files",
|
||||||
"UploadAvatars": "Can upload avatars",
|
"UploadAvatars": "Can upload avatars",
|
||||||
"UseConvos":"Can use conversations"
|
"UseConvos":"Can use conversations",
|
||||||
},
|
|
||||||
|
|
||||||
"LocalPerms": {
|
|
||||||
"ViewTopic": "Can view topics",
|
"ViewTopic": "Can view topics",
|
||||||
"LikeItem": "Can like items",
|
"LikeItem": "Can like items",
|
||||||
"CreateTopic": "Can create topics",
|
"CreateTopic": "Can create topics",
|
||||||
|
|
|
@ -1242,14 +1242,13 @@ func TestPluginManager(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPhrases(t *testing.T) {
|
func TestPhrases(t *testing.T) {
|
||||||
getPhrase := phrases.GetGlobalPermPhrase
|
getPhrase := phrases.GetPermPhrase
|
||||||
tp := func(name string, expects string) {
|
tp := func(name string, expects string) {
|
||||||
res := getPhrase(name)
|
res := getPhrase(name)
|
||||||
expect(t, res == expects, "Not the expected phrase, got '"+res+"' instead")
|
expect(t, res == expects, "Not the expected phrase, got '"+res+"' instead")
|
||||||
}
|
}
|
||||||
tp("BanUsers", "Can ban users")
|
tp("BanUsers", "Can ban users")
|
||||||
tp("NoSuchPerm", "{lang.perms[NoSuchPerm]}")
|
tp("NoSuchPerm", "{lang.perms[NoSuchPerm]}")
|
||||||
getPhrase = phrases.GetLocalPermPhrase
|
|
||||||
tp("ViewTopic", "Can view topics")
|
tp("ViewTopic", "Can view topics")
|
||||||
tp("NoSuchPerm", "{lang.perms[NoSuchPerm]}")
|
tp("NoSuchPerm", "{lang.perms[NoSuchPerm]}")
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
c "github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/common/phrases"
|
p "github.com/Azareal/Gosora/common/phrases"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Forums(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
func Forums(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
|
@ -98,7 +98,7 @@ func ForumsDelete(w http.ResponseWriter, r *http.Request, user c.User, sfid stri
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmMsg := phrases.GetTmplPhrasef("panel_forum_delete_are_you_sure", forum.Name)
|
confirmMsg := p.GetTmplPhrasef("panel_forum_delete_are_you_sure", forum.Name)
|
||||||
yousure := c.AreYouSure{"/panel/forums/delete/submit/" + strconv.Itoa(fid), confirmMsg}
|
yousure := c.AreYouSure{"/panel/forums/delete/submit/" + strconv.Itoa(fid), confirmMsg}
|
||||||
|
|
||||||
pi := c.PanelPage{basePage, tList, yousure}
|
pi := c.PanelPage{basePage, tList, yousure}
|
||||||
|
@ -168,7 +168,7 @@ func ForumsEdit(w http.ResponseWriter, r *http.Request, user c.User, sfid string
|
||||||
|
|
||||||
fid, err := strconv.Atoi(sfid)
|
fid, err := strconv.Atoi(sfid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.SimpleError(phrases.GetErrorPhrase("url_id_must_be_integer"),w,r,basePage.Header)
|
return c.SimpleError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, basePage.Header)
|
||||||
}
|
}
|
||||||
basePage.Header.AddScriptAsync("panel_forum_edit.js")
|
basePage.Header.AddScriptAsync("panel_forum_edit.js")
|
||||||
|
|
||||||
|
@ -341,24 +341,23 @@ func ForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, user c.User,
|
||||||
}
|
}
|
||||||
|
|
||||||
var formattedPermList []c.NameLangToggle
|
var formattedPermList []c.NameLangToggle
|
||||||
|
|
||||||
// TODO: Load the phrases in bulk for efficiency?
|
// TODO: Load the phrases in bulk for efficiency?
|
||||||
// TODO: Reduce the amount of code duplication between this and the group editor. Also, can we grind this down into one line or use a code generator to stay current more easily?
|
// TODO: Reduce the amount of code duplication between this and the group editor. Also, can we grind this down into one line or use a code generator to stay current more easily?
|
||||||
addNameLangToggle := func(permStr string, perm bool) {
|
addToggle := func(permStr string, perm bool) {
|
||||||
formattedPermList = append(formattedPermList, c.NameLangToggle{permStr, phrases.GetLocalPermPhrase(permStr), perm})
|
formattedPermList = append(formattedPermList, c.NameLangToggle{permStr, p.GetPermPhrase(permStr), perm})
|
||||||
}
|
}
|
||||||
addNameLangToggle("ViewTopic", fp.ViewTopic)
|
addToggle("ViewTopic", fp.ViewTopic)
|
||||||
addNameLangToggle("LikeItem", fp.LikeItem)
|
addToggle("LikeItem", fp.LikeItem)
|
||||||
addNameLangToggle("CreateTopic", fp.CreateTopic)
|
addToggle("CreateTopic", fp.CreateTopic)
|
||||||
//<--
|
//<--
|
||||||
addNameLangToggle("EditTopic", fp.EditTopic)
|
addToggle("EditTopic", fp.EditTopic)
|
||||||
addNameLangToggle("DeleteTopic", fp.DeleteTopic)
|
addToggle("DeleteTopic", fp.DeleteTopic)
|
||||||
addNameLangToggle("CreateReply", fp.CreateReply)
|
addToggle("CreateReply", fp.CreateReply)
|
||||||
addNameLangToggle("EditReply", fp.EditReply)
|
addToggle("EditReply", fp.EditReply)
|
||||||
addNameLangToggle("DeleteReply", fp.DeleteReply)
|
addToggle("DeleteReply", fp.DeleteReply)
|
||||||
addNameLangToggle("PinTopic", fp.PinTopic)
|
addToggle("PinTopic", fp.PinTopic)
|
||||||
addNameLangToggle("CloseTopic", fp.CloseTopic)
|
addToggle("CloseTopic", fp.CloseTopic)
|
||||||
addNameLangToggle("MoveTopic", fp.MoveTopic)
|
addToggle("MoveTopic", fp.MoveTopic)
|
||||||
|
|
||||||
if r.FormValue("updated") == "1" {
|
if r.FormValue("updated") == "1" {
|
||||||
basePage.AddNotice("panel_forum_perms_updated")
|
basePage.AddNotice("panel_forum_perms_updated")
|
||||||
|
@ -376,7 +375,7 @@ func ForumsEditPermsAdvanceSubmit(w http.ResponseWriter, r *http.Request, user c
|
||||||
if !user.Perms.ManageForums {
|
if !user.Perms.ManageForums {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
js := (r.PostFormValue("js") == "1")
|
js := r.PostFormValue("js") == "1"
|
||||||
|
|
||||||
fid, gid, err := forumPermsExtractDash(paramList)
|
fid, gid, err := forumPermsExtractDash(paramList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -301,7 +301,7 @@ func GroupsEditPerms(w http.ResponseWriter, r *http.Request, user c.User, sgid s
|
||||||
// TODO: Load the phrases in bulk for efficiency?
|
// TODO: Load the phrases in bulk for efficiency?
|
||||||
var localPerms []c.NameLangToggle
|
var localPerms []c.NameLangToggle
|
||||||
addLocalPerm := func(permStr string, perm bool) {
|
addLocalPerm := func(permStr string, perm bool) {
|
||||||
localPerms = append(localPerms, c.NameLangToggle{permStr, p.GetLocalPermPhrase(permStr), perm})
|
localPerms = append(localPerms, c.NameLangToggle{permStr, p.GetPermPhrase(permStr), perm})
|
||||||
}
|
}
|
||||||
|
|
||||||
addLocalPerm("ViewTopic", g.Perms.ViewTopic)
|
addLocalPerm("ViewTopic", g.Perms.ViewTopic)
|
||||||
|
@ -319,7 +319,7 @@ func GroupsEditPerms(w http.ResponseWriter, r *http.Request, user c.User, sgid s
|
||||||
|
|
||||||
var globalPerms []c.NameLangToggle
|
var globalPerms []c.NameLangToggle
|
||||||
addGlobalPerm := func(permStr string, perm bool) {
|
addGlobalPerm := func(permStr string, perm bool) {
|
||||||
globalPerms = append(globalPerms, c.NameLangToggle{permStr, p.GetGlobalPermPhrase(permStr), perm})
|
globalPerms = append(globalPerms, c.NameLangToggle{permStr, p.GetPermPhrase(permStr), perm})
|
||||||
}
|
}
|
||||||
|
|
||||||
addGlobalPerm("BanUsers", g.Perms.BanUsers)
|
addGlobalPerm("BanUsers", g.Perms.BanUsers)
|
||||||
|
|
|
@ -214,7 +214,7 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
|
||||||
// TODO: Disable stat updates in posts handled by plugin_guilds
|
// TODO: Disable stat updates in posts handled by plugin_guilds
|
||||||
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
|
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
|
||||||
func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
||||||
js := (r.PostFormValue("js") == "1")
|
js := r.PostFormValue("js") == "1"
|
||||||
rid, err := strconv.Atoi(srid)
|
rid, err := strconv.Atoi(srid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)
|
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)
|
||||||
|
@ -282,7 +282,7 @@ func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
|
||||||
// TODO: Refactor this
|
// TODO: Refactor this
|
||||||
// TODO: Disable stat updates in posts handled by plugin_guilds
|
// TODO: Disable stat updates in posts handled by plugin_guilds
|
||||||
func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
||||||
js := (r.PostFormValue("js") == "1")
|
js := r.PostFormValue("js") == "1"
|
||||||
rid, err := strconv.Atoi(srid)
|
rid, err := strconv.Atoi(srid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)
|
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)
|
||||||
|
@ -307,9 +307,11 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
|
if reply.CreatedBy != user.ID {
|
||||||
if !user.Perms.ViewTopic || !user.Perms.DeleteReply {
|
if !user.Perms.ViewTopic || !user.Perms.DeleteReply {
|
||||||
return c.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, user, js)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = reply.Delete()
|
err = reply.Delete()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -501,7 +503,7 @@ func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user c.Use
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
||||||
js := (r.PostFormValue("js") == "1")
|
js := r.PostFormValue("js") == "1"
|
||||||
rid, err := strconv.Atoi(srid)
|
rid, err := strconv.Atoi(srid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, js)
|
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, js)
|
||||||
|
@ -537,7 +539,7 @@ func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User,
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
||||||
js := (r.PostFormValue("js") == "1")
|
js := r.PostFormValue("js") == "1"
|
||||||
rid, err := strconv.Atoi(srid)
|
rid, err := strconv.Atoi(srid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, js)
|
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, js)
|
||||||
|
@ -573,7 +575,7 @@ func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.Use
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
||||||
js := (r.PostFormValue("js") == "1")
|
js := r.PostFormValue("js") == "1"
|
||||||
rid, err := strconv.Atoi(srid)
|
rid, err := strconv.Atoi(srid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)
|
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
//"fmt"
|
//"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -18,7 +19,7 @@ import (
|
||||||
c "github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/common/counters"
|
"github.com/Azareal/Gosora/common/counters"
|
||||||
"github.com/Azareal/Gosora/common/phrases"
|
"github.com/Azareal/Gosora/common/phrases"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
qgen "github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TopicStmts struct {
|
type TopicStmts struct {
|
||||||
|
@ -82,11 +83,11 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic.Tag = postGroup.Tag
|
topic.Tag = postGroup.Tag
|
||||||
if postGroup.IsMod {
|
if postGroup.IsMod {
|
||||||
topic.ClassName = c.Config.StaffCSS
|
topic.ClassName = c.Config.StaffCSS
|
||||||
}
|
}
|
||||||
|
topic.Deletable = user.Perms.DeleteTopic || topic.CreatedBy == user.ID
|
||||||
|
|
||||||
forum, err := c.Forums.Get(topic.ParentID)
|
forum, err := c.Forums.Get(topic.ParentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -616,9 +617,11 @@ func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
|
if topic.CreatedBy != user.ID {
|
||||||
if !user.Perms.ViewTopic || !user.Perms.DeleteTopic {
|
if !user.Perms.ViewTopic || !user.Perms.DeleteTopic {
|
||||||
return c.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, user, js)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We might be able to handle this err better
|
// We might be able to handle this err better
|
||||||
err = topic.Delete()
|
err = topic.Delete()
|
||||||
|
@ -862,7 +865,7 @@ func addTopicAction(action string, t *c.Topic, u c.User) error {
|
||||||
|
|
||||||
// TODO: Refactor this
|
// TODO: Refactor this
|
||||||
func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError {
|
func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError {
|
||||||
js := (r.PostFormValue("js") == "1")
|
js := r.PostFormValue("js") == "1"
|
||||||
tid, err := strconv.Atoi(stid)
|
tid, err := strconv.Atoi(stid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, js)
|
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, js)
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
{{if .CurrentUser.Perms.EditTopic}}<a href='/topic/edit/{{.Topic.ID}}' class="mod_button open_edit" title="{{lang "topic.edit_tooltip"}}" aria-label="{{lang "topic.edit_aria"}}"><button class="username edit_label"></button></a>{{end}}
|
{{if .CurrentUser.Perms.EditTopic}}<a href='/topic/edit/{{.Topic.ID}}' class="mod_button open_edit" title="{{lang "topic.edit_tooltip"}}" aria-label="{{lang "topic.edit_aria"}}"><button class="username edit_label"></button></a>{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if .CurrentUser.Perms.DeleteTopic}}<a href='/topic/delete/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="mod_button" title="{{lang "topic.delete_tooltip"}}" aria-label="{{lang "topic.delete_aria"}}"><button class="username delete_label"></button></a>{{end}}
|
{{if .Topic.Deletable}}<a href='/topic/delete/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="mod_button" title="{{lang "topic.delete_tooltip"}}" aria-label="{{lang "topic.delete_aria"}}"><button class="username delete_label"></button></a>{{end}}
|
||||||
|
|
||||||
{{if .CurrentUser.Perms.CloseTopic}}{{if .Topic.IsClosed}}<a class="mod_button" href='/topic/unlock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' title="{{lang "topic.unlock_tooltip"}}" aria-label="{{lang "topic.unlock_aria"}}"><button class="username unlock_label"></button></a>{{else}}<a href='/topic/lock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="mod_button" title="{{lang "topic.lock_tooltip"}}" aria-label="{{lang "topic.lock_aria"}}"><button class="username lock_label"></button></a>{{end}}{{end}}
|
{{if .CurrentUser.Perms.CloseTopic}}{{if .Topic.IsClosed}}<a class="mod_button" href='/topic/unlock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' title="{{lang "topic.unlock_tooltip"}}" aria-label="{{lang "topic.unlock_aria"}}"><button class="username unlock_label"></button></a>{{else}}<a href='/topic/lock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="mod_button" title="{{lang "topic.lock_tooltip"}}" aria-label="{{lang "topic.lock_aria"}}"><button class="username lock_label"></button></a>{{end}}{{end}}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
|
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
|
||||||
{{if .CurrentUser.Perms.EditTopic}}<a href="/topic/edit/{{.Topic.ID}}" class="action_button open_edit" aria-label="{{lang "topic.edit_aria"}}" data-action="edit"></a>{{end}}
|
{{if .CurrentUser.Perms.EditTopic}}<a href="/topic/edit/{{.Topic.ID}}" class="action_button open_edit" aria-label="{{lang "topic.edit_aria"}}" data-action="edit"></a>{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .CurrentUser.Perms.DeleteTopic}}<a href="/topic/delete/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="action_button delete_item" aria-label="{{lang "topic.delete_aria"}}" data-action="delete"></a>{{end}}
|
{{if .Topic.Deletable}}<a href="/topic/delete/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="action_button delete_item" aria-label="{{lang "topic.delete_aria"}}" data-action="delete"></a>{{end}}
|
||||||
{{if .CurrentUser.Perms.CloseTopic}}
|
{{if .CurrentUser.Perms.CloseTopic}}
|
||||||
{{if .Topic.IsClosed}}<a href='/topic/unlock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="action_button unlock_item" data-action="unlock" aria-label="{{lang "topic.unlock_aria"}}"></a>{{else}}<a href='/topic/lock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="action_button lock_item" data-action="lock" aria-label="{{lang "topic.lock_aria"}}"></a>{{end}}{{end}}
|
{{if .Topic.IsClosed}}<a href='/topic/unlock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="action_button unlock_item" data-action="unlock" aria-label="{{lang "topic.unlock_aria"}}"></a>{{else}}<a href='/topic/lock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="action_button lock_item" data-action="lock" aria-label="{{lang "topic.lock_aria"}}"></a>{{end}}{{end}}
|
||||||
{{if .CurrentUser.Perms.PinTopic}}
|
{{if .CurrentUser.Perms.PinTopic}}
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
{{if not $.Topic.IsClosed or $.CurrentUser.Perms.CloseTopic}}
|
{{if not $.Topic.IsClosed or $.CurrentUser.Perms.CloseTopic}}
|
||||||
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="action_button edit_item" aria-label="{{lang "topic.post_edit_aria"}}" data-action="edit"></a>{{end}}
|
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="action_button edit_item" aria-label="{{lang "topic.post_edit_aria"}}" data-action="edit"></a>{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="action_button delete_item" aria-label="{{lang "topic.post_delete_aria"}}" data-action="delete"></a>{{end}}
|
{{if .Deletable}}<a href="/reply/delete/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="action_button delete_item" aria-label="{{lang "topic.post_delete_aria"}}" data-action="delete"></a>{{end}}
|
||||||
{{if $.CurrentUser.Perms.ViewIPs}}<a href="/users/ips/?ip={{.IP}}" title="{{lang "topic.ip_full_tooltip"}}" class="action_button ip_item_button hide_on_big" aria-label="{{lang "topic.ip_full_aria"}}" data-action="ip"></a>{{end}}
|
{{if $.CurrentUser.Perms.ViewIPs}}<a href="/users/ips/?ip={{.IP}}" title="{{lang "topic.ip_full_tooltip"}}" class="action_button ip_item_button hide_on_big" aria-label="{{lang "topic.ip_full_aria"}}" data-action="ip"></a>{{end}}
|
||||||
<a href="/report/submit/{{.ID}}?s={{$.CurrentUser.Session}}&type=reply" class="action_button report_item" aria-label="{{lang "topic.report_aria"}}" data-action="report"></a>
|
<a href="/report/submit/{{.ID}}?s={{$.CurrentUser.Session}}&type=reply" class="action_button report_item" aria-label="{{lang "topic.report_aria"}}" data-action="report"></a>
|
||||||
<a href="#" class="action_button button_menu"></a>
|
<a href="#" class="action_button button_menu"></a>
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="mod_button" title="{{lang "topic.post_edit_tooltip"}}" aria-label="{{lang "topic.post_edit_aria"}}"><button class="username edit_item edit_label"></button></a>{{end}}
|
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="mod_button" title="{{lang "topic.post_edit_tooltip"}}" aria-label="{{lang "topic.post_edit_aria"}}"><button class="username edit_item edit_label"></button></a>{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="mod_button" title="{{lang "topic.post_delete_tooltip"}}" aria-label="{{lang "topic.post_delete_aria"}}"><button class="username delete_item delete_label"></button></a>{{end}}
|
{{if .Deletable}}<a href="/reply/delete/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="mod_button" title="{{lang "topic.post_delete_tooltip"}}" aria-label="{{lang "topic.post_delete_aria"}}"><button class="username delete_item delete_label"></button></a>{{end}}
|
||||||
{{if $.CurrentUser.Perms.ViewIPs}}<a class="mod_button" href='/users/ips/?ip={{.IP}}' title="{{lang "topic.post_ip_tooltip"}}" aria-label="The poster's IP is {{.IP}}"><button class="username ip_label"></button></a>{{end}}
|
{{if $.CurrentUser.Perms.ViewIPs}}<a class="mod_button" href='/users/ips/?ip={{.IP}}' title="{{lang "topic.post_ip_tooltip"}}" aria-label="The poster's IP is {{.IP}}"><button class="username ip_label"></button></a>{{end}}
|
||||||
<a href="/report/submit/{{.ID}}?s={{$.CurrentUser.Session}}&type=reply" class="mod_button report_item" title="{{lang "topic.post_flag_tooltip"}}" aria-label="{{lang "topic.post_flag_aria"}}" rel="nofollow"><button class="username report_item flag_label"></button></a>
|
<a href="/report/submit/{{.ID}}?s={{$.CurrentUser.Session}}&type=reply" class="mod_button report_item" title="{{lang "topic.post_flag_tooltip"}}" aria-label="{{lang "topic.post_flag_aria"}}" rel="nofollow"><button class="username report_item flag_label"></button></a>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue