Tighten validation on group promotion delete.
Shorten some variable names. Reduce the amount of duplication in the panel group routes. Rename isJs to js here and there. Localise group promotions. Phrases: Rename create_topic_create_topic_button to create_topic_create_button Rename quick_topic.create_topic_button to quick_topic.create_button Rename quick_topic.create_topic_button_short to quick_topic.create_button_short Rename panel_groups_create_create_group_button to panel_groups_create_button Rename panel_word_filters_create_create_word_filter_button to panel_word_filters_create_button Rename panel_pages_create_submit_button to panel_pages_create_button Add panel_group_promotions_create_head Add panel_group_promotions_from Add panel_group_promotions_to Add panel_group_promotions_two_way Add panel_group_promotions_level Add panel_group_promotions_create_button
This commit is contained in:
parent
69e1e8d364
commit
764b9904f1
|
@ -552,7 +552,7 @@
|
|||
"create_topic_name":"Topic Name",
|
||||
"create_topic_content":"Content",
|
||||
"create_topic_placeholder":"Insert content here",
|
||||
"create_topic_create_topic_button":"Create Topic",
|
||||
"create_topic_create_button":"Create Topic",
|
||||
"create_topic_add_file_button":"Add File",
|
||||
|
||||
"quick_topic.aria":"Quick Topic Form",
|
||||
|
@ -561,8 +561,8 @@
|
|||
"quick_topic.whatsup":"What's up?",
|
||||
"quick_topic.content_placeholder":"Insert post here",
|
||||
"quick_topic.add_poll_option_first":"Poll option #0",
|
||||
"quick_topic.create_topic_button":"Create Topic",
|
||||
"quick_topic.create_topic_button_short":"New Topic",
|
||||
"quick_topic.create_button":"Create Topic",
|
||||
"quick_topic.create_button_short":"New Topic",
|
||||
"quick_topic.add_poll_button":"Add Poll",
|
||||
"quick_topic.add_file_button":"Add File",
|
||||
"quick_topic.cancel_button":"Cancel",
|
||||
|
@ -870,7 +870,7 @@
|
|||
"panel_groups_create_name_placeholder":"Administrator",
|
||||
"panel_groups_create_type":"Type",
|
||||
"panel_groups_create_tag":"Tag",
|
||||
"panel_groups_create_create_group_button":"Add Group",
|
||||
"panel_groups_create_button":"Add Group",
|
||||
|
||||
"panel_group_menu_head":"Group Editor",
|
||||
"panel_group_menu_general":"General",
|
||||
|
@ -885,6 +885,13 @@
|
|||
"panel_group_update_button":"Update Group",
|
||||
"panel_group_extended_permissions":"Extended Permissions",
|
||||
|
||||
"panel_group_promotions_create_head":"Add Promotion",
|
||||
"panel_group_promotions_from":"From",
|
||||
"panel_group_promotions_to":"To",
|
||||
"panel_group_promotions_two_way":"Two Way",
|
||||
"panel_group_promotions_level":"Level",
|
||||
"panel_group_promotions_create_button":"Add Promotion",
|
||||
|
||||
"panel_word_filters_head":"Word Filters",
|
||||
"panel_word_filters_to":"to",
|
||||
"panel_word_filters_edit_button_aria":"Edit Word Filter",
|
||||
|
@ -896,7 +903,7 @@
|
|||
"panel_word_filters_create_find_placeholder":"fuck",
|
||||
"panel_word_filters_create_replacement":"Replacement",
|
||||
"panel_word_filters_create_replacement_placeholder":"fudge",
|
||||
"panel_word_filters_create_create_word_filter_button":"Add Filter",
|
||||
"panel_word_filters_create_button":"Add Filter",
|
||||
|
||||
"panel_pages_head":"Page Manager",
|
||||
"panel_pages_edit_button_aria":"Edit Page",
|
||||
|
@ -908,7 +915,7 @@
|
|||
"panel_pages_create_title":"Title",
|
||||
"panel_pages_create_title_placeholder":"Frequently Asked Questions",
|
||||
"panel_pages_create_body_placeholder":"We understand you have a lot of questions.",
|
||||
"panel_pages_create_submit_button":"Create Page",
|
||||
"panel_pages_create_button":"Create Page",
|
||||
|
||||
"panel_pages_edit_head":"Page Editor",
|
||||
"panel_pages_name":"Name",
|
||||
|
|
|
@ -436,7 +436,7 @@ function mainInit(){
|
|||
url: target,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: { isJs: 1 },
|
||||
data: { js: 1 },
|
||||
error: ajaxError,
|
||||
success: function (data, status, xhr) {
|
||||
if("success" in data && data["success"] == "1") return;
|
||||
|
@ -729,7 +729,7 @@ function mainInit(){
|
|||
type: "POST",
|
||||
dataType: "json",
|
||||
error: ajaxError,
|
||||
data: { isJs: "1", edit_item: newContent }
|
||||
data: { js: "1", edit_item: newContent }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -771,7 +771,7 @@ function mainInit(){
|
|||
|
||||
$(".submit_edit").click(function(event) {
|
||||
event.preventDefault();
|
||||
var outData = {isJs: "1"}
|
||||
var outData = {js: "1"}
|
||||
var blockParent = $(this).closest('.editable_parent');
|
||||
blockParent.find('.editable_block').each(function() {
|
||||
var fieldName = this.getAttribute("data-field");
|
||||
|
@ -856,7 +856,7 @@ function mainInit(){
|
|||
url: this.form.getAttribute("action") + "?s=" + me.User.S,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: { "newTheme": this.options[this.selectedIndex].getAttribute("val"), isJs: "1" },
|
||||
data: { "newTheme": this.options[this.selectedIndex].getAttribute("val"), js: "1" },
|
||||
error: ajaxError,
|
||||
success: function (data, status, xhr) {
|
||||
console.log("Theme successfully switched");
|
||||
|
|
|
@ -83,19 +83,19 @@ func CustomPage(w http.ResponseWriter, r *http.Request, user c.User, header *c.H
|
|||
// TODO: Set the cookie domain
|
||||
func ChangeTheme(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||
//headerLite, _ := SimpleUserCheck(w, r, &user)
|
||||
// TODO: Rename isJs to something else, just in case we rewrite the JS side in WebAssembly?
|
||||
isJs := (r.PostFormValue("isJs") == "1")
|
||||
// TODO: Rename js to something else, just in case we rewrite the JS side in WebAssembly?
|
||||
js := (r.PostFormValue("js") == "1")
|
||||
newTheme := c.SanitiseSingleLine(r.PostFormValue("newTheme"))
|
||||
|
||||
theme, ok := c.Themes[newTheme]
|
||||
if !ok || theme.HideFromThemes {
|
||||
return c.LocalErrorJSQ("That theme doesn't exist", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("That theme doesn't exist", w, r, user, js)
|
||||
}
|
||||
|
||||
cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: int(c.Year)}
|
||||
http.SetCookie(w, &cookie)
|
||||
|
||||
if !isJs {
|
||||
if !js {
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
} else {
|
||||
_, _ = w.Write(successJSONBytes)
|
||||
|
|
|
@ -1052,7 +1052,7 @@ func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user c.User) c.R
|
|||
ovList := analyticsVMapToOVList(vMap)
|
||||
|
||||
ex := strings.Split(r.FormValue("ex"), ",")
|
||||
var inEx = func(name string) bool {
|
||||
inEx := func(name string) bool {
|
||||
for _, e := range ex {
|
||||
if e == name {
|
||||
return true
|
||||
|
@ -1134,7 +1134,7 @@ func AnalyticsReferrers(w http.ResponseWriter, r *http.Request, user c.User) c.R
|
|||
}
|
||||
showSpam := r.FormValue("spam") == "1"
|
||||
|
||||
var isSpammy = func(domain string) bool {
|
||||
isSpammy := func(domain string) bool {
|
||||
for _, substr := range c.SpammyDomainBits {
|
||||
if strings.Contains(domain, substr) {
|
||||
return true
|
||||
|
|
|
@ -10,14 +10,14 @@ import (
|
|||
p "github.com/Azareal/Gosora/common/phrases"
|
||||
)
|
||||
|
||||
func Groups(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||
basePage, ferr := buildBasePage(w, r, &user, "groups", "groups")
|
||||
func Groups(w http.ResponseWriter, r *http.Request, u c.User) c.RouteError {
|
||||
bPage, ferr := buildBasePage(w, r, &u, "groups", "groups")
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
page, _ := strconv.Atoi(r.FormValue("page"))
|
||||
perPage := 15
|
||||
offset, page, lastPage := c.PageOffset(basePage.Stats.Groups, page, perPage)
|
||||
offset, page, lastPage := c.PageOffset(bPage.Stats.Groups, page, perPage)
|
||||
|
||||
// Skip the 'Unknown' group
|
||||
offset++
|
||||
|
@ -25,7 +25,7 @@ func Groups(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
|||
var count int
|
||||
var groupList []c.GroupAdmin
|
||||
groups, _ := c.Groups.GetRange(offset, 0)
|
||||
for _, group := range groups {
|
||||
for _, g := range groups {
|
||||
if count == perPage {
|
||||
break
|
||||
}
|
||||
|
@ -33,33 +33,33 @@ func Groups(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
|||
var rankClass string
|
||||
var canDelete = false
|
||||
|
||||
// TODO: Use a switch for this
|
||||
// TODO: Localise this
|
||||
if group.IsAdmin {
|
||||
switch {
|
||||
case g.IsAdmin:
|
||||
rank = "Admin"
|
||||
rankClass = "admin"
|
||||
} else if group.IsMod {
|
||||
case g.IsMod:
|
||||
rank = "Mod"
|
||||
rankClass = "mod"
|
||||
} else if group.IsBanned {
|
||||
case g.IsBanned:
|
||||
rank = "Banned"
|
||||
rankClass = "banned"
|
||||
} else if group.ID == 6 {
|
||||
case g.ID == 6:
|
||||
rank = "Guest"
|
||||
rankClass = "guest"
|
||||
} else {
|
||||
default:
|
||||
rank = "Member"
|
||||
rankClass = "member"
|
||||
}
|
||||
|
||||
canEdit := user.Perms.EditGroup && (!group.IsAdmin || user.Perms.EditGroupAdmin) && (!group.IsMod || user.Perms.EditGroupSuperMod)
|
||||
groupList = append(groupList, c.GroupAdmin{group.ID, group.Name, rank, rankClass, canEdit, canDelete})
|
||||
canEdit := u.Perms.EditGroup && (!g.IsAdmin || u.Perms.EditGroupAdmin) && (!g.IsMod || u.Perms.EditGroupSuperMod)
|
||||
groupList = append(groupList, c.GroupAdmin{g.ID, g.Name, rank, rankClass, canEdit, canDelete})
|
||||
count++
|
||||
}
|
||||
|
||||
pageList := c.Paginate(page, lastPage, 5)
|
||||
pi := c.PanelGroupPage{basePage, groupList, c.Paginator{pageList, page, lastPage}}
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_groups",&pi})
|
||||
pi := c.PanelGroupPage{bPage, groupList, c.Paginator{pageList, page, lastPage}}
|
||||
return renderTemplate("panel", w, r, bPage.Header, c.Panel{bPage, "", "", "panel_groups", &pi})
|
||||
}
|
||||
|
||||
func GroupsEdit(w http.ResponseWriter, r *http.Request, user c.User, sgid string) c.RouteError {
|
||||
|
@ -75,38 +75,32 @@ func GroupsEdit(w http.ResponseWriter, r *http.Request, user c.User, sgid string
|
|||
if err != nil {
|
||||
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
||||
}
|
||||
|
||||
group, err := c.Groups.Get(gid)
|
||||
g, err := c.Groups.Get(gid)
|
||||
if err == sql.ErrNoRows {
|
||||
//log.Print("aaaaa monsters")
|
||||
return c.NotFound(w, r, basePage.Header)
|
||||
} else if err != nil {
|
||||
return c.InternalError(err, w, r)
|
||||
}
|
||||
|
||||
if group.IsAdmin && !user.Perms.EditGroupAdmin {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
|
||||
}
|
||||
if group.IsMod && !user.Perms.EditGroupSuperMod {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
|
||||
ferr = groupCheck(w,r,user,g,err)
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
|
||||
var rank string
|
||||
switch {
|
||||
case group.IsAdmin:
|
||||
case g.IsAdmin:
|
||||
rank = "Admin"
|
||||
case group.IsMod:
|
||||
case g.IsMod:
|
||||
rank = "Mod"
|
||||
case group.IsBanned:
|
||||
case g.IsBanned:
|
||||
rank = "Banned"
|
||||
case group.ID == 6:
|
||||
case g.ID == 6:
|
||||
rank = "Guest"
|
||||
default:
|
||||
rank = "Member"
|
||||
}
|
||||
disableRank := !user.Perms.EditGroupGlobalPerms || (group.ID == 6)
|
||||
disableRank := !user.Perms.EditGroupGlobalPerms || (g.ID == 6)
|
||||
|
||||
pi := c.PanelEditGroupPage{basePage, group.ID, group.Name, group.Tag, rank, disableRank}
|
||||
pi := c.PanelEditGroupPage{basePage, g.ID, g.Name, g.Tag, rank, disableRank}
|
||||
return renderTemplate("panel_group_edit", w, r, basePage.Header, pi)
|
||||
}
|
||||
|
||||
|
@ -123,19 +117,14 @@ func GroupsEditPromotions(w http.ResponseWriter, r *http.Request, user c.User, s
|
|||
if err != nil {
|
||||
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
||||
}
|
||||
|
||||
g, err := c.Groups.Get(gid)
|
||||
if err == sql.ErrNoRows {
|
||||
//log.Print("aaaaa monsters")
|
||||
return c.NotFound(w, r, basePage.Header)
|
||||
} else if err != nil {
|
||||
return c.InternalError(err, w, r)
|
||||
}
|
||||
if g.IsAdmin && !user.Perms.EditGroupAdmin {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
|
||||
}
|
||||
if g.IsMod && !user.Perms.EditGroupSuperMod {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
|
||||
ferr = groupCheck(w,r,user,g,err)
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
|
||||
promotions, err := c.GroupPromotions.GetByGroup(g.ID)
|
||||
|
@ -146,13 +135,13 @@ func GroupsEditPromotions(w http.ResponseWriter, r *http.Request, user c.User, s
|
|||
for i, promote := range promotions {
|
||||
fg, err := c.Groups.Get(promote.From)
|
||||
if err == sql.ErrNoRows {
|
||||
fg = &c.Group{Name:"Deleted Group"}
|
||||
fg = &c.Group{Name: "Deleted Group"}
|
||||
} else if err != nil {
|
||||
return c.InternalError(err, w, r)
|
||||
}
|
||||
tg, err := c.Groups.Get(promote.To)
|
||||
if err == sql.ErrNoRows {
|
||||
tg = &c.Group{Name:"Deleted Group"}
|
||||
tg = &c.Group{Name: "Deleted Group"}
|
||||
} else if err != nil {
|
||||
return c.InternalError(err, w, r)
|
||||
}
|
||||
|
@ -180,6 +169,21 @@ func GroupsEditPromotions(w http.ResponseWriter, r *http.Request, user c.User, s
|
|||
return renderTemplate("panel_group_edit_promotions", w, r, basePage.Header, pi)
|
||||
}
|
||||
|
||||
func groupCheck(w http.ResponseWriter, r *http.Request, user c.User, g *c.Group, err error) c.RouteError {
|
||||
if err == sql.ErrNoRows {
|
||||
return c.LocalError("No such group.", w, r, user)
|
||||
} else if err != nil {
|
||||
return c.InternalError(err, w, r)
|
||||
}
|
||||
if g.IsAdmin && !user.Perms.EditGroupAdmin {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
|
||||
}
|
||||
if g.IsMod && !user.Perms.EditGroupSuperMod {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GroupsPromotionsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User, sgid string) c.RouteError {
|
||||
if !user.Perms.EditGroup {
|
||||
return c.NoPermissions(w, r, user)
|
||||
|
@ -206,34 +210,18 @@ func GroupsPromotionsCreateSubmit(w http.ResponseWriter, r *http.Request, user c
|
|||
}
|
||||
|
||||
g, err := c.Groups.Get(from)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.LocalError("No such group.",w, r, user)
|
||||
} else if err != nil {
|
||||
return c.InternalError(err, w, r)
|
||||
ferr := groupCheck(w, r, user, g, err)
|
||||
if err != nil {
|
||||
return ferr
|
||||
}
|
||||
if g.IsAdmin && !user.Perms.EditGroupAdmin {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
|
||||
}
|
||||
if g.IsMod && !user.Perms.EditGroupSuperMod {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
|
||||
}
|
||||
|
||||
g, err = c.Groups.Get(to)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.LocalError("No such group.",w, r, user)
|
||||
} else if err != nil {
|
||||
return c.InternalError(err, w, r)
|
||||
ferr = groupCheck(w, r, user, g, err)
|
||||
if err != nil {
|
||||
return ferr
|
||||
}
|
||||
if g.IsAdmin && !user.Perms.EditGroupAdmin {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
|
||||
}
|
||||
if g.IsMod && !user.Perms.EditGroupSuperMod {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
|
||||
}
|
||||
|
||||
_, err = c.GroupPromotions.Create(from, to, twoWay, level)
|
||||
if err != nil {
|
||||
return c.InternalError(err,w,r)
|
||||
return c.InternalError(err, w, r)
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/panel/groups/edit/promotions/"+strconv.Itoa(gid), http.StatusSeeOther)
|
||||
|
@ -246,7 +234,7 @@ func GroupsPromotionsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c
|
|||
}
|
||||
spl := strings.Split(sspl, "-")
|
||||
if len(spl) < 2 {
|
||||
return c.LocalError("need two params",w,r,user)
|
||||
return c.LocalError("need two params", w, r, user)
|
||||
}
|
||||
gid, err := strconv.Atoi(spl[0])
|
||||
if err != nil {
|
||||
|
@ -257,9 +245,26 @@ func GroupsPromotionsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c
|
|||
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
||||
}
|
||||
|
||||
pro, err := c.GroupPromotions.Get(pid)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.LocalError("That group promotion doesn't exist", w, r, user)
|
||||
} else if err != nil {
|
||||
return c.InternalError(err, w, r)
|
||||
}
|
||||
|
||||
g, err := c.Groups.Get(pro.From)
|
||||
ferr := groupCheck(w, r, user, g, err)
|
||||
if err != nil {
|
||||
return ferr
|
||||
}
|
||||
g, err = c.Groups.Get(pro.To)
|
||||
ferr = groupCheck(w, r, user, g, err)
|
||||
if err != nil {
|
||||
return ferr
|
||||
}
|
||||
err = c.GroupPromotions.Delete(pid)
|
||||
if err != nil {
|
||||
return c.InternalError(err,w,r)
|
||||
return c.InternalError(err, w, r)
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/panel/groups/edit/promotions/"+strconv.Itoa(gid), http.StatusSeeOther)
|
||||
|
@ -360,14 +365,10 @@ func GroupsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sgid
|
|||
if err == sql.ErrNoRows {
|
||||
//log.Print("aaaaa monsters")
|
||||
return c.NotFound(w, r, nil)
|
||||
} else if err != nil {
|
||||
return c.InternalError(err, w, r)
|
||||
}
|
||||
if group.IsAdmin && !user.Perms.EditGroupAdmin {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
|
||||
}
|
||||
if group.IsMod && !user.Perms.EditGroupSuperMod {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
|
||||
ferr = groupCheck(w, r, user, group, err)
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
|
||||
gname := r.FormValue("group-name")
|
||||
|
@ -447,31 +448,24 @@ func GroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user c.User,
|
|||
if err == sql.ErrNoRows {
|
||||
//log.Print("aaaaa monsters o.o")
|
||||
return c.NotFound(w, r, nil)
|
||||
} else if err != nil {
|
||||
return c.InternalError(err, w, r)
|
||||
}
|
||||
if group.IsAdmin && !user.Perms.EditGroupAdmin {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
|
||||
}
|
||||
if group.IsMod && !user.Perms.EditGroupSuperMod {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
|
||||
ferr = groupCheck(w, r, user, group, err)
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
|
||||
// TODO: Don't unset perms we don't have permission to set?
|
||||
pmap := make(map[string]bool)
|
||||
|
||||
if user.Perms.EditGroupLocalPerms {
|
||||
for _, perm := range c.LocalPermList {
|
||||
pvalue := r.PostFormValue("group-perm-" + perm)
|
||||
pmap[perm] = (pvalue == "1")
|
||||
}
|
||||
}
|
||||
|
||||
if user.Perms.EditGroupGlobalPerms {
|
||||
for _, perm := range c.GlobalPermList {
|
||||
pvalue := r.PostFormValue("group-perm-" + perm)
|
||||
pmap[perm] = (pvalue == "1")
|
||||
pCheck := func(hasPerm bool, perms []string) {
|
||||
if hasPerm {
|
||||
for _, perm := range perms {
|
||||
pvalue := r.PostFormValue("group-perm-" + perm)
|
||||
pmap[perm] = (pvalue == "1")
|
||||
}
|
||||
}
|
||||
}
|
||||
pCheck(user.Perms.EditGroupLocalPerms, c.LocalPermList)
|
||||
pCheck(user.Perms.EditGroupGlobalPerms, c.GlobalPermList)
|
||||
|
||||
err = group.UpdatePerms(pmap)
|
||||
if err != nil {
|
||||
|
@ -499,19 +493,19 @@ func GroupsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
|
|||
|
||||
var isAdmin, isMod, isBanned bool
|
||||
if user.Perms.EditGroupGlobalPerms {
|
||||
groupType := r.PostFormValue("group-type")
|
||||
if groupType == "Admin" {
|
||||
switch r.PostFormValue("group-type") {
|
||||
case "Admin":
|
||||
if !user.Perms.EditGroupAdmin {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_admin"), w, r, user)
|
||||
}
|
||||
isAdmin = true
|
||||
isMod = true
|
||||
} else if groupType == "Mod" {
|
||||
case "Mod":
|
||||
if !user.Perms.EditGroupSuperMod {
|
||||
return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_supermod"), w, r, user)
|
||||
}
|
||||
isMod = true
|
||||
} else if groupType == "Banned" {
|
||||
case "Banned":
|
||||
isBanned = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ func WordFilters(w http.ResponseWriter, r *http.Request, user c.User) c.RouteErr
|
|||
}
|
||||
|
||||
pi := c.PanelPage{basePage, tList, filterList}
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_word_filters",&pi})
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_word_filters", &pi})
|
||||
}
|
||||
|
||||
func WordFiltersCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||
|
@ -36,23 +36,23 @@ func WordFiltersCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User
|
|||
if !user.Perms.EditSettings {
|
||||
return c.NoPermissions(w, r, user)
|
||||
}
|
||||
isJs := (r.PostFormValue("js") == "1")
|
||||
js := (r.PostFormValue("js") == "1")
|
||||
|
||||
// ? - We're not doing a full sanitise here, as it would be useful if admins were able to put down rules for replacing things with HTML, etc.
|
||||
find := strings.TrimSpace(r.PostFormValue("find"))
|
||||
if find == "" {
|
||||
return c.LocalErrorJSQ("You need to specify what word you want to match", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("You need to specify what word you want to match", w, r, user, js)
|
||||
}
|
||||
|
||||
// Unlike with find, it's okay if we leave this blank, as this means that the admin wants to remove the word entirely with no replacement
|
||||
replacement := strings.TrimSpace(r.PostFormValue("replacement"))
|
||||
replace := strings.TrimSpace(r.PostFormValue("replacement"))
|
||||
|
||||
err := c.WordFilters.Create(find, replacement)
|
||||
err := c.WordFilters.Create(find, replace)
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
return successRedirect("/panel/settings/word-filters/", w, r, isJs)
|
||||
return successRedirect("/panel/settings/word-filters/", w, r, js)
|
||||
}
|
||||
|
||||
// TODO: Implement this as a non-JS fallback
|
||||
|
@ -67,7 +67,7 @@ func WordFiltersEdit(w http.ResponseWriter, r *http.Request, user c.User, wfid s
|
|||
_ = wfid
|
||||
|
||||
pi := c.PanelPage{basePage, tList, nil}
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_word_filters_edit",&pi})
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_word_filters_edit", &pi})
|
||||
}
|
||||
|
||||
func WordFiltersEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, wfid string) c.RouteError {
|
||||
|
@ -75,28 +75,26 @@ func WordFiltersEditSubmit(w http.ResponseWriter, r *http.Request, user c.User,
|
|||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
// TODO: Either call it isJs or js rather than flip-flopping back and forth across the routes x.x
|
||||
isJs := (r.PostFormValue("isJs") == "1")
|
||||
js := (r.PostFormValue("js") == "1")
|
||||
if !user.Perms.EditSettings {
|
||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||
return c.NoPermissionsJSQ(w, r, user, js)
|
||||
}
|
||||
|
||||
id, err := strconv.Atoi(wfid)
|
||||
if err != nil {
|
||||
return c.LocalErrorJSQ("The word filter ID must be an integer.", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("The word filter ID must be an integer.", w, r, user, js)
|
||||
}
|
||||
|
||||
find := strings.TrimSpace(r.PostFormValue("find"))
|
||||
if find == "" {
|
||||
return c.LocalErrorJSQ("You need to specify what word you want to match", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("You need to specify what word you want to match", w, r, user, js)
|
||||
}
|
||||
|
||||
// Unlike with find, it's okay if we leave this blank, as this means that the admin wants to remove the word entirely with no replacement
|
||||
replacement := strings.TrimSpace(r.PostFormValue("replacement"))
|
||||
replace := strings.TrimSpace(r.PostFormValue("replacement"))
|
||||
|
||||
err = c.WordFilters.Update(id, find, replacement)
|
||||
err = c.WordFilters.Update(id, find, replace)
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/panel/settings/word-filters/", http.StatusSeeOther)
|
||||
|
@ -109,19 +107,19 @@ func WordFiltersDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User
|
|||
return ferr
|
||||
}
|
||||
|
||||
isJs := (r.PostFormValue("isJs") == "1")
|
||||
js := (r.PostFormValue("js") == "1")
|
||||
if !user.Perms.EditSettings {
|
||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||
return c.NoPermissionsJSQ(w, r, user, js)
|
||||
}
|
||||
|
||||
id, err := strconv.Atoi(wfid)
|
||||
if err != nil {
|
||||
return c.LocalErrorJSQ("The word filter ID must be an integer.", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("The word filter ID must be an integer.", w, r, user, js)
|
||||
}
|
||||
|
||||
err = c.WordFilters.Delete(id)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.LocalErrorJSQ("This word filter doesn't exist", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("This word filter doesn't exist", w, r, user, js)
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/panel/settings/word-filters/", http.StatusSeeOther)
|
||||
|
|
|
@ -118,7 +118,7 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
|
|||
}
|
||||
|
||||
// Make sure the indices are sequential to avoid out of bounds issues
|
||||
var seqPollInputItems = make(map[int]string)
|
||||
seqPollInputItems := make(map[int]string)
|
||||
for i := 0; i < len(pollInputItems); i++ {
|
||||
seqPollInputItems[i] = pollInputItems[i]
|
||||
}
|
||||
|
@ -282,24 +282,24 @@ func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
|
|||
// TODO: Refactor this
|
||||
// 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 {
|
||||
isJs := (r.PostFormValue("isJs") == "1")
|
||||
js := (r.PostFormValue("js") == "1")
|
||||
rid, err := strconv.Atoi(srid)
|
||||
if err != nil {
|
||||
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, isJs)
|
||||
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)
|
||||
}
|
||||
|
||||
reply, err := c.Rstore.Get(rid)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.PreErrorJSQ("The reply you tried to delete doesn't exist.", w, r, isJs)
|
||||
return c.PreErrorJSQ("The reply you tried to delete doesn't exist.", w, r, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
topic, err := c.Topics.Get(reply.ParentID)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, isJs)
|
||||
return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
// TODO: Add hooks to make use of headerLite
|
||||
|
@ -308,12 +308,12 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
|
|||
return ferr
|
||||
}
|
||||
if !user.Perms.ViewTopic || !user.Perms.DeleteReply {
|
||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||
return c.NoPermissionsJSQ(w, r, user, js)
|
||||
}
|
||||
|
||||
err = reply.Delete()
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
skip, rerr := lite.Hooks.VhookSkippable("action_end_delete_reply", reply.ID, &user)
|
||||
|
@ -322,7 +322,7 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
|
|||
}
|
||||
|
||||
//log.Printf("Reply #%d was deleted by c.User #%d", rid, user.ID)
|
||||
if !isJs {
|
||||
if !js {
|
||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
|
||||
} else {
|
||||
w.Write(successJSONBytes)
|
||||
|
@ -334,15 +334,15 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
|
|||
wcount := c.WordCount(reply.Content)
|
||||
err = replyCreator.DecreasePostStats(wcount, false)
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
} else if err != sql.ErrNoRows {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
err = c.ModLogs.Create("delete", reply.ParentID, "reply", user.LastIP, user.ID)
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -501,34 +501,34 @@ 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 {
|
||||
isJs := (r.PostFormValue("js") == "1")
|
||||
js := (r.PostFormValue("js") == "1")
|
||||
rid, err := strconv.Atoi(srid)
|
||||
if err != nil {
|
||||
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, js)
|
||||
}
|
||||
|
||||
reply, err := c.Prstore.Get(rid)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, isJs)
|
||||
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
creator, err := c.Users.Get(reply.CreatedBy)
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
// ? Does the admin understand that this group perm affects this?
|
||||
if user.ID != creator.ID && !user.Perms.EditReply {
|
||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||
return c.NoPermissionsJSQ(w, r, user, js)
|
||||
}
|
||||
|
||||
err = reply.SetBody(r.PostFormValue("edit_item"))
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
if !isJs {
|
||||
if !js {
|
||||
http.Redirect(w, r, "/user/"+strconv.Itoa(creator.ID)+"#reply-"+strconv.Itoa(rid), http.StatusSeeOther)
|
||||
} else {
|
||||
w.Write(successJSONBytes)
|
||||
|
@ -537,35 +537,34 @@ 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 {
|
||||
isJs := (r.PostFormValue("isJs") == "1")
|
||||
|
||||
js := (r.PostFormValue("js") == "1")
|
||||
rid, err := strconv.Atoi(srid)
|
||||
if err != nil {
|
||||
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, js)
|
||||
}
|
||||
|
||||
reply, err := c.Prstore.Get(rid)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, isJs)
|
||||
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
creator, err := c.Users.Get(reply.CreatedBy)
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
if user.ID != creator.ID && !user.Perms.DeleteReply {
|
||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||
return c.NoPermissionsJSQ(w, r, user, js)
|
||||
}
|
||||
|
||||
err = reply.Delete()
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
//log.Printf("The profile post '%d' was deleted by c.User #%d", reply.ID, user.ID)
|
||||
|
||||
if !isJs {
|
||||
if !js {
|
||||
//http.Redirect(w,r, "/user/" + strconv.Itoa(creator.ID), http.StatusSeeOther)
|
||||
} else {
|
||||
w.Write(successJSONBytes)
|
||||
|
@ -574,25 +573,25 @@ 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 {
|
||||
isJs := (r.PostFormValue("isJs") == "1")
|
||||
js := (r.PostFormValue("js") == "1")
|
||||
|
||||
rid, err := strconv.Atoi(srid)
|
||||
if err != nil {
|
||||
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, isJs)
|
||||
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)
|
||||
}
|
||||
|
||||
reply, err := c.Rstore.Get(rid)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.PreErrorJSQ("You can't like something which doesn't exist!", w, r, isJs)
|
||||
return c.PreErrorJSQ("You can't like something which doesn't exist!", w, r, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
topic, err := c.Topics.Get(reply.ParentID)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, isJs)
|
||||
return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
// TODO: Add hooks to make use of headerLite
|
||||
|
@ -601,31 +600,31 @@ func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
|
|||
return ferr
|
||||
}
|
||||
if !user.Perms.ViewTopic || !user.Perms.LikeItem {
|
||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||
return c.NoPermissionsJSQ(w, r, user, js)
|
||||
}
|
||||
if reply.CreatedBy == user.ID {
|
||||
return c.LocalErrorJSQ("You can't like your own replies", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("You can't like your own replies", w, r, user, js)
|
||||
}
|
||||
|
||||
_, err = c.Users.Get(reply.CreatedBy)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return c.LocalErrorJSQ("The target user doesn't exist", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("The target user doesn't exist", w, r, user, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
err = reply.Like(user.ID)
|
||||
if err == c.ErrAlreadyLiked {
|
||||
return c.LocalErrorJSQ("You've already liked this!", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("You've already liked this!", w, r, user, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
// ! Be careful about leaking per-route permission state with &user
|
||||
alert := c.Alert{ActorID: user.ID, TargetUserID: reply.CreatedBy, Event: "like", ElementType: "post", ElementID: rid, Actor: &user}
|
||||
err = c.AddActivityAndNotifyTarget(alert)
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
skip, rerr := lite.Hooks.VhookSkippable("action_end_like_reply", reply.ID, &user)
|
||||
|
@ -633,7 +632,7 @@ func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
|
|||
return rerr
|
||||
}
|
||||
|
||||
if !isJs {
|
||||
if !js {
|
||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
|
||||
} else {
|
||||
_, _ = w.Write(successJSONBytes)
|
||||
|
|
|
@ -14,7 +14,7 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID s
|
|||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
isJs := (r.PostFormValue("isJs") == "1")
|
||||
js := (r.PostFormValue("js") == "1")
|
||||
|
||||
itemID, err := strconv.Atoi(sitemID)
|
||||
if err != nil {
|
||||
|
@ -104,7 +104,7 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID s
|
|||
}
|
||||
counters.PostCounter.Bump()
|
||||
|
||||
if !isJs {
|
||||
if !js {
|
||||
// TODO: Redirect back to where we came from
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
} else {
|
||||
|
|
|
@ -508,17 +508,17 @@ func uploadFilesWithHash(w http.ResponseWriter, r *http.Request, user c.User, di
|
|||
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
|
||||
// TODO: Disable stat updates in posts handled by plugin_guilds
|
||||
func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError {
|
||||
isJs := (r.PostFormValue("js") == "1")
|
||||
js := (r.PostFormValue("js") == "1")
|
||||
tid, err := strconv.Atoi(stid)
|
||||
if err != nil {
|
||||
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, isJs)
|
||||
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, js)
|
||||
}
|
||||
|
||||
topic, err := c.Topics.Get(tid)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.PreErrorJSQ("The topic you tried to edit doesn't exist.", w, r, isJs)
|
||||
return c.PreErrorJSQ("The topic you tried to edit doesn't exist.", w, r, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
// TODO: Add hooks to make use of headerLite
|
||||
|
@ -527,10 +527,10 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
|
|||
return ferr
|
||||
}
|
||||
if !user.Perms.ViewTopic || !user.Perms.EditTopic {
|
||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||
return c.NoPermissionsJSQ(w, r, user, js)
|
||||
}
|
||||
if topic.IsClosed && !user.Perms.CloseTopic {
|
||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||
return c.NoPermissionsJSQ(w, r, user, js)
|
||||
}
|
||||
|
||||
err = topic.Update(r.PostFormValue("topic_name"), r.PostFormValue("topic_content"))
|
||||
|
@ -538,26 +538,26 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
|
|||
if err != nil {
|
||||
switch err {
|
||||
case c.ErrNoTitle:
|
||||
return c.LocalErrorJSQ("This topic doesn't have a title", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("This topic doesn't have a title", w, r, user, js)
|
||||
case c.ErrLongTitle:
|
||||
return c.LocalErrorJSQ("The length of the title is too long, max: "+strconv.Itoa(c.Config.MaxTopicTitleLength), w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("The length of the title is too long, max: "+strconv.Itoa(c.Config.MaxTopicTitleLength), w, r, user, js)
|
||||
case c.ErrNoBody:
|
||||
return c.LocalErrorJSQ("This topic doesn't have a body", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("This topic doesn't have a body", w, r, user, js)
|
||||
}
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
err = c.Forums.UpdateLastTopic(topic.ID, user.ID, topic.ParentID)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
// TODO: Avoid the load to get this faster?
|
||||
topic, err = c.Topics.Get(topic.ID)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.PreErrorJSQ("The updated topic doesn't exist.", w, r, isJs)
|
||||
return c.PreErrorJSQ("The updated topic doesn't exist.", w, r, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
skip, rerr := lite.Hooks.VhookSkippable("action_end_edit_topic", topic.ID, &user)
|
||||
|
@ -565,12 +565,12 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
|
|||
return rerr
|
||||
}
|
||||
|
||||
if !isJs {
|
||||
if !js {
|
||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
||||
} else {
|
||||
outBytes, err := json.Marshal(JsonReply{c.ParseMessage(topic.Content, topic.ParentID, "forums")})
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
w.Write(outBytes)
|
||||
}
|
||||
|
@ -582,7 +582,7 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
|
|||
func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||
// TODO: Move this to some sort of middleware
|
||||
var tids []int
|
||||
var isJs = false
|
||||
js := false
|
||||
if c.ReqIsJson(r) {
|
||||
if r.Body == nil {
|
||||
return c.PreErrorJS("No request body", w, r)
|
||||
|
@ -591,7 +591,7 @@ func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
|
|||
if err != nil {
|
||||
return c.PreErrorJS("We weren't able to parse your data", w, r)
|
||||
}
|
||||
isJs = true
|
||||
js = true
|
||||
} else {
|
||||
tid, err := strconv.Atoi(r.URL.Path[len("/topic/delete/submit/"):])
|
||||
if err != nil {
|
||||
|
@ -600,15 +600,15 @@ func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
|
|||
tids = append(tids, tid)
|
||||
}
|
||||
if len(tids) == 0 {
|
||||
return c.LocalErrorJSQ("You haven't provided any IDs", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("You haven't provided any IDs", w, r, user, js)
|
||||
}
|
||||
|
||||
for _, tid := range tids {
|
||||
topic, err := c.Topics.Get(tid)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.PreErrorJSQ("The topic you tried to delete doesn't exist.", w, r, isJs)
|
||||
return c.PreErrorJSQ("The topic you tried to delete doesn't exist.", w, r, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
// TODO: Add hooks to make use of headerLite
|
||||
|
@ -617,24 +617,24 @@ func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
|
|||
return ferr
|
||||
}
|
||||
if !user.Perms.ViewTopic || !user.Perms.DeleteTopic {
|
||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||
return c.NoPermissionsJSQ(w, r, user, js)
|
||||
}
|
||||
|
||||
// We might be able to handle this err better
|
||||
err = topic.Delete()
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
err = c.ModLogs.Create("delete", tid, "topic", user.LastIP, user.ID)
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
// ? - We might need to add soft-delete before we can do an action reply for this
|
||||
/*_, err = stmts.createActionReply.Exec(tid,"delete",ipaddress,user.ID)
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err,w,r,isJs)
|
||||
return c.InternalErrorJSQ(err,w,r,js)
|
||||
}*/
|
||||
|
||||
// TODO: Do a bulk delete action hook?
|
||||
|
@ -712,7 +712,7 @@ func UnstickTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, sti
|
|||
func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||
// TODO: Move this to some sort of middleware
|
||||
var tids []int
|
||||
var isJs = false
|
||||
js := false
|
||||
if c.ReqIsJson(r) {
|
||||
if r.Body == nil {
|
||||
return c.PreErrorJS("No request body", w, r)
|
||||
|
@ -721,7 +721,7 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
|
|||
if err != nil {
|
||||
return c.PreErrorJS("We weren't able to parse your data", w, r)
|
||||
}
|
||||
isJs = true
|
||||
js = true
|
||||
} else {
|
||||
tid, err := strconv.Atoi(r.URL.Path[len("/topic/lock/submit/"):])
|
||||
if err != nil {
|
||||
|
@ -730,15 +730,15 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
|
|||
tids = append(tids, tid)
|
||||
}
|
||||
if len(tids) == 0 {
|
||||
return c.LocalErrorJSQ("You haven't provided any IDs", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("You haven't provided any IDs", w, r, user, js)
|
||||
}
|
||||
|
||||
for _, tid := range tids {
|
||||
topic, err := c.Topics.Get(tid)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.PreErrorJSQ("The topic you tried to lock doesn't exist.", w, r, isJs)
|
||||
return c.PreErrorJSQ("The topic you tried to lock doesn't exist.", w, r, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
// TODO: Add hooks to make use of headerLite
|
||||
|
@ -747,17 +747,17 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
|
|||
return ferr
|
||||
}
|
||||
if !user.Perms.ViewTopic || !user.Perms.CloseTopic {
|
||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||
return c.NoPermissionsJSQ(w, r, user, js)
|
||||
}
|
||||
|
||||
err = topic.Lock()
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
err = addTopicAction("lock", topic, user)
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
// TODO: Do a bulk lock action hook?
|
||||
|
@ -863,17 +863,17 @@ func addTopicAction(action string, topic *c.Topic, user c.User) error {
|
|||
|
||||
// TODO: Refactor this
|
||||
func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError {
|
||||
isJs := (r.PostFormValue("isJs") == "1")
|
||||
js := (r.PostFormValue("js") == "1")
|
||||
tid, err := strconv.Atoi(stid)
|
||||
if err != nil {
|
||||
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, isJs)
|
||||
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, js)
|
||||
}
|
||||
|
||||
topic, err := c.Topics.Get(tid)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.PreErrorJSQ("The requested topic doesn't exist.", w, r, isJs)
|
||||
return c.PreErrorJSQ("The requested topic doesn't exist.", w, r, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
// TODO: Add hooks to make use of headerLite
|
||||
|
@ -882,32 +882,32 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
|
|||
return ferr
|
||||
}
|
||||
if !user.Perms.ViewTopic || !user.Perms.LikeItem {
|
||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||
return c.NoPermissionsJSQ(w, r, user, js)
|
||||
}
|
||||
if topic.CreatedBy == user.ID {
|
||||
return c.LocalErrorJSQ("You can't like your own topics", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("You can't like your own topics", w, r, user, js)
|
||||
}
|
||||
|
||||
_, err = c.Users.Get(topic.CreatedBy)
|
||||
if err != nil && err == sql.ErrNoRows {
|
||||
return c.LocalErrorJSQ("The target user doesn't exist", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("The target user doesn't exist", w, r, user, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
score := 1
|
||||
err = topic.Like(score, user.ID)
|
||||
if err == c.ErrAlreadyLiked {
|
||||
return c.LocalErrorJSQ("You already liked this", w, r, user, isJs)
|
||||
return c.LocalErrorJSQ("You already liked this", w, r, user, js)
|
||||
} else if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
// ! Be careful about leaking per-route permission state with &user
|
||||
alert := c.Alert{ActorID: user.ID, TargetUserID: topic.CreatedBy, Event: "like", ElementType: "topic", ElementID: tid, Actor: &user}
|
||||
err = c.AddActivityAndNotifyTarget(alert)
|
||||
if err != nil {
|
||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||
return c.InternalErrorJSQ(err, w, r, js)
|
||||
}
|
||||
|
||||
skip, rerr := lite.Hooks.VhookSkippable("action_end_like_topic", topic.ID, &user)
|
||||
|
@ -915,7 +915,7 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
|
|||
return rerr
|
||||
}
|
||||
|
||||
if !isJs {
|
||||
if !js {
|
||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
||||
} else {
|
||||
_, _ = w.Write(successJSONBytes)
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<div class="formitem"><textarea form="quick_post_form" class="large" id="topic_content" name="topic-content" placeholder="{{lang "create_topic_placeholder"}}" required></textarea></div>
|
||||
</div>
|
||||
<div class="formrow">
|
||||
<button form="quick_post_form" name="topic-button" class="formbutton">{{lang "create_topic_create_topic_button"}}</button>
|
||||
<button form="quick_post_form" name="topic-button" class="formbutton">{{lang "create_topic_create_button"}}</button>
|
||||
{{if .CurrentUser.Perms.UploadFiles}}
|
||||
<input name="quick_topic_upload_files" form="quick_post_form" id="quick_topic_upload_files" multiple type="file" style="display: none;" />
|
||||
<label for="quick_topic_upload_files" class="formbutton add_file_button">{{lang "create_topic_add_file_button"}}</label>{{end}}
|
||||
|
|
|
@ -1,22 +1,20 @@
|
|||
</div>
|
||||
<aside class="midRight sidebar">{{dock "rightSidebar" .Header }}</aside>
|
||||
<aside class="midRight sidebar">{{dock "rightSidebar" .Header}}</aside>
|
||||
</div>
|
||||
<div class="footBlock">
|
||||
<div class="footLeft"></div>
|
||||
<div class="footer">
|
||||
{{dock "footer" .Header }}
|
||||
{{dock "footer" .Header}}
|
||||
<div id="poweredByHolder" class="footerBit">
|
||||
<div id="poweredBy">
|
||||
<a id="poweredByName" href="https://github.com/Azareal/Gosora">{{lang "footer_powered_by"}}</a><span id="poweredByDash"> - </span><span id="poweredByMaker">{{lang "footer_made_with_love"}}</span>
|
||||
</div>
|
||||
{{if .CurrentUser.IsAdmin}}<div title="start to before tmpl" class="elapsed">{{.Header.Elapsed1}}</div><div title="start to footer" class="elapsed">{{elapsed .Header.StartedAt}}</div>{{end}}
|
||||
{{/**{{if .CurrentUser.IsAdmin}}**/}}<div title="start to before tmpl" class="elapsed">{{.Header.Elapsed1}}</div><div title="start to footer" class="elapsed">{{elapsed .Header.StartedAt}}</div>{{/**{{end}}**/}}
|
||||
<form action="/theme/" method="post">
|
||||
<div id="themeSelector">
|
||||
<select id="themeSelectorSelect" name="themeSelector" aria-label="{{lang "footer_theme_selector_aria"}}">
|
||||
{{range .Header.Themes}}
|
||||
<select id="themeSelectorSelect" name="themeSelector" aria-label="{{lang "footer_theme_selector_aria"}}">{{range .Header.Themes}}
|
||||
{{if not .HideFromThemes}}<option val="{{.Name}}"{{if eq $.Header.Theme.Name .Name}} selected{{end}}>{{.FriendlyName}}</option>{{end}}
|
||||
{{end}}
|
||||
</select>
|
||||
{{end}}</select>
|
||||
<noscript><input type="submit" /></noscript>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -24,12 +24,12 @@
|
|||
|
||||
{{if .CurrentUser.Perms.EditGroup}}
|
||||
<div class="colstack_item colstack_head">
|
||||
<div class="rowitem"><h1>Add Promotion</h1></div>
|
||||
<div class="rowitem"><h1>{{lang "panel_group_promotions_create_head"}}</h1></div>
|
||||
</div>
|
||||
<div class="colstack_item the_form">
|
||||
<form action="/panel/groups/promotions/create/submit/{{.ID}}?s={{.CurrentUser.Session}}" method="post">
|
||||
<div class="formrow">
|
||||
<div class="formitem formlabel"><a>From</a></div>
|
||||
<div class="formitem formlabel"><a>{{lang "panel_group_promotions_from"}}</a></div>
|
||||
<div class="formitem">
|
||||
<select name="from">
|
||||
{{range .Groups}}<option value="{{.ID}}">{{.Name}}</option>{{end}}
|
||||
|
@ -37,7 +37,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="formrow">
|
||||
<div class="formitem formlabel"><a>To</a></div>
|
||||
<div class="formitem formlabel"><a>{{lang "panel_group_promotions_to"}}</a></div>
|
||||
<div class="formitem">
|
||||
<select name="to">
|
||||
{{range .Groups}}<option value="{{.ID}}">{{.Name}}</option>{{end}}
|
||||
|
@ -45,7 +45,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="formrow">
|
||||
<div class="formitem formlabel"><a>Two Way</a></div>
|
||||
<div class="formitem formlabel"><a>{{lang "panel_group_promotions_two_way"}}</a></div>
|
||||
<div class="formitem">
|
||||
<select name="two-way" disabled>
|
||||
<option value=1>{{lang "option_yes"}}</option>
|
||||
|
@ -54,11 +54,11 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="formrow">
|
||||
<div class="formitem formlabel"><a>Level</a></div>
|
||||
<div class="formitem formlabel"><a>{{lang "panel_group_promotions_level"}}</a></div>
|
||||
<div class="formitem"><input name="level" type="number" value=0 /></div>
|
||||
</div>
|
||||
<div class="formrow form_button_row">
|
||||
<div class="formitem"><button name="panel-button" class="formbutton">{{lang "panel_groups_create_create_group_button"}}</button></div>
|
||||
<div class="formitem"><button name="panel-button" class="formbutton">{{lang "panel_group_promotions_create_button"}}</button></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<div class="formitem"><input name="replacement" type="text" placeholder="{{lang "panel_word_filters_create_replacement_placeholder"}}" /></div>
|
||||
</div>
|
||||
<div class="formrow">
|
||||
<div class="formitem"><button name="panel-button" class="formbutton form_middle_button">{{lang "panel_word_filters_create_create_word_filter_button"}}</button></div>
|
||||
<div class="formitem"><button name="panel-button" class="formbutton form_middle_button">{{lang "panel_word_filters_create_button"}}</button></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
|
@ -15,7 +15,7 @@
|
|||
</div>
|
||||
<div class="formrow quick_button_row">
|
||||
<div class="formitem">
|
||||
<button form="quick_post_form" class="formbutton">{{lang "quick_topic.create_topic_button"}}</button>
|
||||
<button form="quick_post_form" class="formbutton">{{lang "quick_topic.create_button"}}</button>
|
||||
<button form="quick_post_form" class="formbutton" id="add_poll_button">{{lang "quick_topic.add_poll_button"}}</button>
|
||||
{{if .CurrentUser.Perms.UploadFiles}}
|
||||
<input name="upload_files" form="quick_post_form" id="upload_files" multiple type="file" class="auto_hide" />
|
||||
|
|
|
@ -486,7 +486,7 @@ h2 {
|
|||
white-space: nowrap;
|
||||
}
|
||||
.topic_list_title_block .create_topic_opt a:before {
|
||||
content: "{{lang "quick_topic.create_topic_button" . }}";
|
||||
content: "{{lang "quick_topic.create_button" . }}";
|
||||
}
|
||||
.topic_list_title_block .mod_opt a:before {
|
||||
content: "{{lang "topic_list.moderate" . }}";
|
||||
|
@ -1312,7 +1312,7 @@ input[type=checkbox]:checked + label .sel {
|
|||
display: none;
|
||||
}
|
||||
.topic_list_title_block .create_topic_opt a:before {
|
||||
content: "{{lang "quick_topic.create_topic_button_short" . }}";
|
||||
content: "{{lang "quick_topic.create_button_short" . }}";
|
||||
}
|
||||
.topic_list_title_block .mod_opt a:before {
|
||||
content: "{{lang "topic_list.moderate_short" . }}";
|
||||
|
|
Loading…
Reference in New Issue