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_name":"Topic Name",
|
||||||
"create_topic_content":"Content",
|
"create_topic_content":"Content",
|
||||||
"create_topic_placeholder":"Insert content here",
|
"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",
|
"create_topic_add_file_button":"Add File",
|
||||||
|
|
||||||
"quick_topic.aria":"Quick Topic Form",
|
"quick_topic.aria":"Quick Topic Form",
|
||||||
|
@ -561,8 +561,8 @@
|
||||||
"quick_topic.whatsup":"What's up?",
|
"quick_topic.whatsup":"What's up?",
|
||||||
"quick_topic.content_placeholder":"Insert post here",
|
"quick_topic.content_placeholder":"Insert post here",
|
||||||
"quick_topic.add_poll_option_first":"Poll option #0",
|
"quick_topic.add_poll_option_first":"Poll option #0",
|
||||||
"quick_topic.create_topic_button":"Create Topic",
|
"quick_topic.create_button":"Create Topic",
|
||||||
"quick_topic.create_topic_button_short":"New Topic",
|
"quick_topic.create_button_short":"New Topic",
|
||||||
"quick_topic.add_poll_button":"Add Poll",
|
"quick_topic.add_poll_button":"Add Poll",
|
||||||
"quick_topic.add_file_button":"Add File",
|
"quick_topic.add_file_button":"Add File",
|
||||||
"quick_topic.cancel_button":"Cancel",
|
"quick_topic.cancel_button":"Cancel",
|
||||||
|
@ -870,7 +870,7 @@
|
||||||
"panel_groups_create_name_placeholder":"Administrator",
|
"panel_groups_create_name_placeholder":"Administrator",
|
||||||
"panel_groups_create_type":"Type",
|
"panel_groups_create_type":"Type",
|
||||||
"panel_groups_create_tag":"Tag",
|
"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_head":"Group Editor",
|
||||||
"panel_group_menu_general":"General",
|
"panel_group_menu_general":"General",
|
||||||
|
@ -885,6 +885,13 @@
|
||||||
"panel_group_update_button":"Update Group",
|
"panel_group_update_button":"Update Group",
|
||||||
"panel_group_extended_permissions":"Extended Permissions",
|
"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_head":"Word Filters",
|
||||||
"panel_word_filters_to":"to",
|
"panel_word_filters_to":"to",
|
||||||
"panel_word_filters_edit_button_aria":"Edit Word Filter",
|
"panel_word_filters_edit_button_aria":"Edit Word Filter",
|
||||||
|
@ -896,7 +903,7 @@
|
||||||
"panel_word_filters_create_find_placeholder":"fuck",
|
"panel_word_filters_create_find_placeholder":"fuck",
|
||||||
"panel_word_filters_create_replacement":"Replacement",
|
"panel_word_filters_create_replacement":"Replacement",
|
||||||
"panel_word_filters_create_replacement_placeholder":"fudge",
|
"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_head":"Page Manager",
|
||||||
"panel_pages_edit_button_aria":"Edit Page",
|
"panel_pages_edit_button_aria":"Edit Page",
|
||||||
|
@ -908,7 +915,7 @@
|
||||||
"panel_pages_create_title":"Title",
|
"panel_pages_create_title":"Title",
|
||||||
"panel_pages_create_title_placeholder":"Frequently Asked Questions",
|
"panel_pages_create_title_placeholder":"Frequently Asked Questions",
|
||||||
"panel_pages_create_body_placeholder":"We understand you have a lot of 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_edit_head":"Page Editor",
|
||||||
"panel_pages_name":"Name",
|
"panel_pages_name":"Name",
|
||||||
|
|
|
@ -436,7 +436,7 @@ function mainInit(){
|
||||||
url: target,
|
url: target,
|
||||||
type: "POST",
|
type: "POST",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
data: { isJs: 1 },
|
data: { js: 1 },
|
||||||
error: ajaxError,
|
error: ajaxError,
|
||||||
success: function (data, status, xhr) {
|
success: function (data, status, xhr) {
|
||||||
if("success" in data && data["success"] == "1") return;
|
if("success" in data && data["success"] == "1") return;
|
||||||
|
@ -729,7 +729,7 @@ function mainInit(){
|
||||||
type: "POST",
|
type: "POST",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
error: ajaxError,
|
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) {
|
$(".submit_edit").click(function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var outData = {isJs: "1"}
|
var outData = {js: "1"}
|
||||||
var blockParent = $(this).closest('.editable_parent');
|
var blockParent = $(this).closest('.editable_parent');
|
||||||
blockParent.find('.editable_block').each(function() {
|
blockParent.find('.editable_block').each(function() {
|
||||||
var fieldName = this.getAttribute("data-field");
|
var fieldName = this.getAttribute("data-field");
|
||||||
|
@ -856,7 +856,7 @@ function mainInit(){
|
||||||
url: this.form.getAttribute("action") + "?s=" + me.User.S,
|
url: this.form.getAttribute("action") + "?s=" + me.User.S,
|
||||||
type: "POST",
|
type: "POST",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
data: { "newTheme": this.options[this.selectedIndex].getAttribute("val"), isJs: "1" },
|
data: { "newTheme": this.options[this.selectedIndex].getAttribute("val"), js: "1" },
|
||||||
error: ajaxError,
|
error: ajaxError,
|
||||||
success: function (data, status, xhr) {
|
success: function (data, status, xhr) {
|
||||||
console.log("Theme successfully switched");
|
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
|
// TODO: Set the cookie domain
|
||||||
func ChangeTheme(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
func ChangeTheme(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
//headerLite, _ := SimpleUserCheck(w, r, &user)
|
//headerLite, _ := SimpleUserCheck(w, r, &user)
|
||||||
// TODO: Rename isJs to something else, just in case we rewrite the JS side in WebAssembly?
|
// TODO: Rename js to something else, just in case we rewrite the JS side in WebAssembly?
|
||||||
isJs := (r.PostFormValue("isJs") == "1")
|
js := (r.PostFormValue("js") == "1")
|
||||||
newTheme := c.SanitiseSingleLine(r.PostFormValue("newTheme"))
|
newTheme := c.SanitiseSingleLine(r.PostFormValue("newTheme"))
|
||||||
|
|
||||||
theme, ok := c.Themes[newTheme]
|
theme, ok := c.Themes[newTheme]
|
||||||
if !ok || theme.HideFromThemes {
|
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)}
|
cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: int(c.Year)}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
|
|
||||||
if !isJs {
|
if !js {
|
||||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||||
} else {
|
} else {
|
||||||
_, _ = w.Write(successJSONBytes)
|
_, _ = w.Write(successJSONBytes)
|
||||||
|
|
|
@ -1052,7 +1052,7 @@ func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user c.User) c.R
|
||||||
ovList := analyticsVMapToOVList(vMap)
|
ovList := analyticsVMapToOVList(vMap)
|
||||||
|
|
||||||
ex := strings.Split(r.FormValue("ex"), ",")
|
ex := strings.Split(r.FormValue("ex"), ",")
|
||||||
var inEx = func(name string) bool {
|
inEx := func(name string) bool {
|
||||||
for _, e := range ex {
|
for _, e := range ex {
|
||||||
if e == name {
|
if e == name {
|
||||||
return true
|
return true
|
||||||
|
@ -1134,7 +1134,7 @@ func AnalyticsReferrers(w http.ResponseWriter, r *http.Request, user c.User) c.R
|
||||||
}
|
}
|
||||||
showSpam := r.FormValue("spam") == "1"
|
showSpam := r.FormValue("spam") == "1"
|
||||||
|
|
||||||
var isSpammy = func(domain string) bool {
|
isSpammy := func(domain string) bool {
|
||||||
for _, substr := range c.SpammyDomainBits {
|
for _, substr := range c.SpammyDomainBits {
|
||||||
if strings.Contains(domain, substr) {
|
if strings.Contains(domain, substr) {
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -10,14 +10,14 @@ import (
|
||||||
p "github.com/Azareal/Gosora/common/phrases"
|
p "github.com/Azareal/Gosora/common/phrases"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Groups(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
func Groups(w http.ResponseWriter, r *http.Request, u c.User) c.RouteError {
|
||||||
basePage, ferr := buildBasePage(w, r, &user, "groups", "groups")
|
bPage, ferr := buildBasePage(w, r, &u, "groups", "groups")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
page, _ := strconv.Atoi(r.FormValue("page"))
|
page, _ := strconv.Atoi(r.FormValue("page"))
|
||||||
perPage := 15
|
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
|
// Skip the 'Unknown' group
|
||||||
offset++
|
offset++
|
||||||
|
@ -25,7 +25,7 @@ func Groups(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
var count int
|
var count int
|
||||||
var groupList []c.GroupAdmin
|
var groupList []c.GroupAdmin
|
||||||
groups, _ := c.Groups.GetRange(offset, 0)
|
groups, _ := c.Groups.GetRange(offset, 0)
|
||||||
for _, group := range groups {
|
for _, g := range groups {
|
||||||
if count == perPage {
|
if count == perPage {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -33,33 +33,33 @@ func Groups(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
var rankClass string
|
var rankClass string
|
||||||
var canDelete = false
|
var canDelete = false
|
||||||
|
|
||||||
// TODO: Use a switch for this
|
|
||||||
// TODO: Localise this
|
// TODO: Localise this
|
||||||
if group.IsAdmin {
|
switch {
|
||||||
|
case g.IsAdmin:
|
||||||
rank = "Admin"
|
rank = "Admin"
|
||||||
rankClass = "admin"
|
rankClass = "admin"
|
||||||
} else if group.IsMod {
|
case g.IsMod:
|
||||||
rank = "Mod"
|
rank = "Mod"
|
||||||
rankClass = "mod"
|
rankClass = "mod"
|
||||||
} else if group.IsBanned {
|
case g.IsBanned:
|
||||||
rank = "Banned"
|
rank = "Banned"
|
||||||
rankClass = "banned"
|
rankClass = "banned"
|
||||||
} else if group.ID == 6 {
|
case g.ID == 6:
|
||||||
rank = "Guest"
|
rank = "Guest"
|
||||||
rankClass = "guest"
|
rankClass = "guest"
|
||||||
} else {
|
default:
|
||||||
rank = "Member"
|
rank = "Member"
|
||||||
rankClass = "member"
|
rankClass = "member"
|
||||||
}
|
}
|
||||||
|
|
||||||
canEdit := user.Perms.EditGroup && (!group.IsAdmin || user.Perms.EditGroupAdmin) && (!group.IsMod || user.Perms.EditGroupSuperMod)
|
canEdit := u.Perms.EditGroup && (!g.IsAdmin || u.Perms.EditGroupAdmin) && (!g.IsMod || u.Perms.EditGroupSuperMod)
|
||||||
groupList = append(groupList, c.GroupAdmin{group.ID, group.Name, rank, rankClass, canEdit, canDelete})
|
groupList = append(groupList, c.GroupAdmin{g.ID, g.Name, rank, rankClass, canEdit, canDelete})
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
|
|
||||||
pageList := c.Paginate(page, lastPage, 5)
|
pageList := c.Paginate(page, lastPage, 5)
|
||||||
pi := c.PanelGroupPage{basePage, groupList, c.Paginator{pageList, page, lastPage}}
|
pi := c.PanelGroupPage{bPage, groupList, c.Paginator{pageList, page, lastPage}}
|
||||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_groups",&pi})
|
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 {
|
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 {
|
if err != nil {
|
||||||
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
||||||
}
|
}
|
||||||
|
g, err := c.Groups.Get(gid)
|
||||||
group, err := c.Groups.Get(gid)
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
//log.Print("aaaaa monsters")
|
//log.Print("aaaaa monsters")
|
||||||
return c.NotFound(w, r, basePage.Header)
|
return c.NotFound(w, r, basePage.Header)
|
||||||
} else if err != nil {
|
|
||||||
return c.InternalError(err, w, r)
|
|
||||||
}
|
}
|
||||||
|
ferr = groupCheck(w,r,user,g,err)
|
||||||
if group.IsAdmin && !user.Perms.EditGroupAdmin {
|
if ferr != nil {
|
||||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
|
return ferr
|
||||||
}
|
|
||||||
if group.IsMod && !user.Perms.EditGroupSuperMod {
|
|
||||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var rank string
|
var rank string
|
||||||
switch {
|
switch {
|
||||||
case group.IsAdmin:
|
case g.IsAdmin:
|
||||||
rank = "Admin"
|
rank = "Admin"
|
||||||
case group.IsMod:
|
case g.IsMod:
|
||||||
rank = "Mod"
|
rank = "Mod"
|
||||||
case group.IsBanned:
|
case g.IsBanned:
|
||||||
rank = "Banned"
|
rank = "Banned"
|
||||||
case group.ID == 6:
|
case g.ID == 6:
|
||||||
rank = "Guest"
|
rank = "Guest"
|
||||||
default:
|
default:
|
||||||
rank = "Member"
|
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)
|
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 {
|
if err != nil {
|
||||||
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
g, err := c.Groups.Get(gid)
|
g, err := c.Groups.Get(gid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
//log.Print("aaaaa monsters")
|
//log.Print("aaaaa monsters")
|
||||||
return c.NotFound(w, r, basePage.Header)
|
return c.NotFound(w, r, basePage.Header)
|
||||||
} else if err != nil {
|
|
||||||
return c.InternalError(err, w, r)
|
|
||||||
}
|
}
|
||||||
if g.IsAdmin && !user.Perms.EditGroupAdmin {
|
ferr = groupCheck(w,r,user,g,err)
|
||||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
|
if ferr != nil {
|
||||||
}
|
return ferr
|
||||||
if g.IsMod && !user.Perms.EditGroupSuperMod {
|
|
||||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
promotions, err := c.GroupPromotions.GetByGroup(g.ID)
|
promotions, err := c.GroupPromotions.GetByGroup(g.ID)
|
||||||
|
@ -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)
|
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 {
|
func GroupsPromotionsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User, sgid string) c.RouteError {
|
||||||
if !user.Perms.EditGroup {
|
if !user.Perms.EditGroup {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
|
@ -206,31 +210,15 @@ func GroupsPromotionsCreateSubmit(w http.ResponseWriter, r *http.Request, user c
|
||||||
}
|
}
|
||||||
|
|
||||||
g, err := c.Groups.Get(from)
|
g, err := c.Groups.Get(from)
|
||||||
if err == sql.ErrNoRows {
|
ferr := groupCheck(w, r, user, g, err)
|
||||||
return c.LocalError("No such group.",w, r, user)
|
if err != nil {
|
||||||
} else if err != nil {
|
return ferr
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
g, err = c.Groups.Get(to)
|
g, err = c.Groups.Get(to)
|
||||||
if err == sql.ErrNoRows {
|
ferr = groupCheck(w, r, user, g, err)
|
||||||
return c.LocalError("No such group.",w, r, user)
|
if err != nil {
|
||||||
} else if err != nil {
|
return ferr
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = c.GroupPromotions.Create(from, to, twoWay, level)
|
_, err = c.GroupPromotions.Create(from, to, twoWay, level)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
|
@ -257,6 +245,23 @@ func GroupsPromotionsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c
|
||||||
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
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)
|
err = c.GroupPromotions.Delete(pid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
|
@ -360,14 +365,10 @@ func GroupsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sgid
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
//log.Print("aaaaa monsters")
|
//log.Print("aaaaa monsters")
|
||||||
return c.NotFound(w, r, nil)
|
return c.NotFound(w, r, nil)
|
||||||
} else if err != nil {
|
|
||||||
return c.InternalError(err, w, r)
|
|
||||||
}
|
}
|
||||||
if group.IsAdmin && !user.Perms.EditGroupAdmin {
|
ferr = groupCheck(w, r, user, group, err)
|
||||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
|
if ferr != nil {
|
||||||
}
|
return ferr
|
||||||
if group.IsMod && !user.Perms.EditGroupSuperMod {
|
|
||||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gname := r.FormValue("group-name")
|
gname := r.FormValue("group-name")
|
||||||
|
@ -447,31 +448,24 @@ func GroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user c.User,
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
//log.Print("aaaaa monsters o.o")
|
//log.Print("aaaaa monsters o.o")
|
||||||
return c.NotFound(w, r, nil)
|
return c.NotFound(w, r, nil)
|
||||||
} else if err != nil {
|
|
||||||
return c.InternalError(err, w, r)
|
|
||||||
}
|
}
|
||||||
if group.IsAdmin && !user.Perms.EditGroupAdmin {
|
ferr = groupCheck(w, r, user, group, err)
|
||||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
|
if ferr != nil {
|
||||||
}
|
return ferr
|
||||||
if group.IsMod && !user.Perms.EditGroupSuperMod {
|
|
||||||
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Don't unset perms we don't have permission to set?
|
||||||
pmap := make(map[string]bool)
|
pmap := make(map[string]bool)
|
||||||
|
pCheck := func(hasPerm bool, perms []string) {
|
||||||
if user.Perms.EditGroupLocalPerms {
|
if hasPerm {
|
||||||
for _, perm := range c.LocalPermList {
|
for _, perm := range perms {
|
||||||
pvalue := r.PostFormValue("group-perm-" + perm)
|
pvalue := r.PostFormValue("group-perm-" + perm)
|
||||||
pmap[perm] = (pvalue == "1")
|
pmap[perm] = (pvalue == "1")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.Perms.EditGroupGlobalPerms {
|
|
||||||
for _, perm := range c.GlobalPermList {
|
|
||||||
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)
|
err = group.UpdatePerms(pmap)
|
||||||
if err != nil {
|
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
|
var isAdmin, isMod, isBanned bool
|
||||||
if user.Perms.EditGroupGlobalPerms {
|
if user.Perms.EditGroupGlobalPerms {
|
||||||
groupType := r.PostFormValue("group-type")
|
switch r.PostFormValue("group-type") {
|
||||||
if groupType == "Admin" {
|
case "Admin":
|
||||||
if !user.Perms.EditGroupAdmin {
|
if !user.Perms.EditGroupAdmin {
|
||||||
return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_admin"), w, r, user)
|
return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_admin"), w, r, user)
|
||||||
}
|
}
|
||||||
isAdmin = true
|
isAdmin = true
|
||||||
isMod = true
|
isMod = true
|
||||||
} else if groupType == "Mod" {
|
case "Mod":
|
||||||
if !user.Perms.EditGroupSuperMod {
|
if !user.Perms.EditGroupSuperMod {
|
||||||
return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_supermod"), w, r, user)
|
return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_supermod"), w, r, user)
|
||||||
}
|
}
|
||||||
isMod = true
|
isMod = true
|
||||||
} else if groupType == "Banned" {
|
case "Banned":
|
||||||
isBanned = true
|
isBanned = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,23 +36,23 @@ func WordFiltersCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User
|
||||||
if !user.Perms.EditSettings {
|
if !user.Perms.EditSettings {
|
||||||
return c.NoPermissions(w, r, user)
|
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.
|
// ? - 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"))
|
find := strings.TrimSpace(r.PostFormValue("find"))
|
||||||
if 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
|
// 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 {
|
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
|
// TODO: Implement this as a non-JS fallback
|
||||||
|
@ -75,28 +75,26 @@ func WordFiltersEditSubmit(w http.ResponseWriter, r *http.Request, user c.User,
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
// TODO: Either call it isJs or js rather than flip-flopping back and forth across the routes x.x
|
js := (r.PostFormValue("js") == "1")
|
||||||
isJs := (r.PostFormValue("isJs") == "1")
|
|
||||||
if !user.Perms.EditSettings {
|
if !user.Perms.EditSettings {
|
||||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := strconv.Atoi(wfid)
|
id, err := strconv.Atoi(wfid)
|
||||||
if err != nil {
|
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"))
|
find := strings.TrimSpace(r.PostFormValue("find"))
|
||||||
if 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
|
// 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 {
|
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)
|
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
|
return ferr
|
||||||
}
|
}
|
||||||
|
|
||||||
isJs := (r.PostFormValue("isJs") == "1")
|
js := (r.PostFormValue("js") == "1")
|
||||||
if !user.Perms.EditSettings {
|
if !user.Perms.EditSettings {
|
||||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := strconv.Atoi(wfid)
|
id, err := strconv.Atoi(wfid)
|
||||||
if err != nil {
|
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)
|
err = c.WordFilters.Delete(id)
|
||||||
if err == sql.ErrNoRows {
|
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)
|
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
|
// 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++ {
|
for i := 0; i < len(pollInputItems); i++ {
|
||||||
seqPollInputItems[i] = 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: 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 {
|
||||||
isJs := (r.PostFormValue("isJs") == "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, isJs)
|
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := c.Rstore.Get(rid)
|
reply, err := c.Rstore.Get(rid)
|
||||||
if err == sql.ErrNoRows {
|
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 {
|
} 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)
|
topic, err := c.Topics.Get(reply.ParentID)
|
||||||
if err == sql.ErrNoRows {
|
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 {
|
} 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
|
// 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
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.DeleteReply {
|
if !user.Perms.ViewTopic || !user.Perms.DeleteReply {
|
||||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = reply.Delete()
|
err = reply.Delete()
|
||||||
if err != nil {
|
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)
|
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)
|
//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)
|
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
|
||||||
} else {
|
} else {
|
||||||
w.Write(successJSONBytes)
|
w.Write(successJSONBytes)
|
||||||
|
@ -334,15 +334,15 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
|
||||||
wcount := c.WordCount(reply.Content)
|
wcount := c.WordCount(reply.Content)
|
||||||
err = replyCreator.DecreasePostStats(wcount, false)
|
err = replyCreator.DecreasePostStats(wcount, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
} else if err != sql.ErrNoRows {
|
} 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)
|
err = c.ModLogs.Create("delete", reply.ParentID, "reply", user.LastIP, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
return nil
|
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 {
|
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)
|
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, isJs)
|
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := c.Prstore.Get(rid)
|
reply, err := c.Prstore.Get(rid)
|
||||||
if err == sql.ErrNoRows {
|
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 {
|
} 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)
|
creator, err := c.Users.Get(reply.CreatedBy)
|
||||||
if err != nil {
|
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?
|
// ? Does the admin understand that this group perm affects this?
|
||||||
if user.ID != creator.ID && !user.Perms.EditReply {
|
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"))
|
err = reply.SetBody(r.PostFormValue("edit_item"))
|
||||||
if err != nil {
|
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)
|
http.Redirect(w, r, "/user/"+strconv.Itoa(creator.ID)+"#reply-"+strconv.Itoa(rid), http.StatusSeeOther)
|
||||||
} else {
|
} else {
|
||||||
w.Write(successJSONBytes)
|
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 {
|
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)
|
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, isJs)
|
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := c.Prstore.Get(rid)
|
reply, err := c.Prstore.Get(rid)
|
||||||
if err == sql.ErrNoRows {
|
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 {
|
} 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)
|
creator, err := c.Users.Get(reply.CreatedBy)
|
||||||
if err != nil {
|
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 {
|
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()
|
err = reply.Delete()
|
||||||
if err != nil {
|
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)
|
//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)
|
//http.Redirect(w,r, "/user/" + strconv.Itoa(creator.ID), http.StatusSeeOther)
|
||||||
} else {
|
} else {
|
||||||
w.Write(successJSONBytes)
|
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 {
|
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)
|
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, isJs)
|
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := c.Rstore.Get(rid)
|
reply, err := c.Rstore.Get(rid)
|
||||||
if err == sql.ErrNoRows {
|
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 {
|
} 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)
|
topic, err := c.Topics.Get(reply.ParentID)
|
||||||
if err == sql.ErrNoRows {
|
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 {
|
} 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
|
// 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
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.LikeItem {
|
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 {
|
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)
|
_, err = c.Users.Get(reply.CreatedBy)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
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 {
|
} else if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = reply.Like(user.ID)
|
err = reply.Like(user.ID)
|
||||||
if err == c.ErrAlreadyLiked {
|
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 {
|
} 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
|
// ! 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}
|
alert := c.Alert{ActorID: user.ID, TargetUserID: reply.CreatedBy, Event: "like", ElementType: "post", ElementID: rid, Actor: &user}
|
||||||
err = c.AddActivityAndNotifyTarget(alert)
|
err = c.AddActivityAndNotifyTarget(alert)
|
||||||
if err != nil {
|
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)
|
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
|
return rerr
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isJs {
|
if !js {
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
|
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
|
||||||
} else {
|
} else {
|
||||||
_, _ = w.Write(successJSONBytes)
|
_, _ = w.Write(successJSONBytes)
|
||||||
|
|
|
@ -14,7 +14,7 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID s
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
isJs := (r.PostFormValue("isJs") == "1")
|
js := (r.PostFormValue("js") == "1")
|
||||||
|
|
||||||
itemID, err := strconv.Atoi(sitemID)
|
itemID, err := strconv.Atoi(sitemID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -104,7 +104,7 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID s
|
||||||
}
|
}
|
||||||
counters.PostCounter.Bump()
|
counters.PostCounter.Bump()
|
||||||
|
|
||||||
if !isJs {
|
if !js {
|
||||||
// TODO: Redirect back to where we came from
|
// TODO: Redirect back to where we came from
|
||||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||||
} else {
|
} 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: 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
|
// 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 {
|
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)
|
tid, err := strconv.Atoi(stid)
|
||||||
if err != nil {
|
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)
|
topic, err := c.Topics.Get(tid)
|
||||||
if err == sql.ErrNoRows {
|
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 {
|
} 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
|
// 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
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.EditTopic {
|
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 {
|
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"))
|
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 {
|
if err != nil {
|
||||||
switch err {
|
switch err {
|
||||||
case c.ErrNoTitle:
|
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:
|
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:
|
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)
|
err = c.Forums.UpdateLastTopic(topic.ID, user.ID, topic.ParentID)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
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?
|
// TODO: Avoid the load to get this faster?
|
||||||
topic, err = c.Topics.Get(topic.ID)
|
topic, err = c.Topics.Get(topic.ID)
|
||||||
if err == sql.ErrNoRows {
|
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 {
|
} 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)
|
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
|
return rerr
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isJs {
|
if !js {
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
||||||
} else {
|
} else {
|
||||||
outBytes, err := json.Marshal(JsonReply{c.ParseMessage(topic.Content, topic.ParentID, "forums")})
|
outBytes, err := json.Marshal(JsonReply{c.ParseMessage(topic.Content, topic.ParentID, "forums")})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
w.Write(outBytes)
|
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 {
|
func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
// TODO: Move this to some sort of middleware
|
// TODO: Move this to some sort of middleware
|
||||||
var tids []int
|
var tids []int
|
||||||
var isJs = false
|
js := false
|
||||||
if c.ReqIsJson(r) {
|
if c.ReqIsJson(r) {
|
||||||
if r.Body == nil {
|
if r.Body == nil {
|
||||||
return c.PreErrorJS("No request body", w, r)
|
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 {
|
if err != nil {
|
||||||
return c.PreErrorJS("We weren't able to parse your data", w, r)
|
return c.PreErrorJS("We weren't able to parse your data", w, r)
|
||||||
}
|
}
|
||||||
isJs = true
|
js = true
|
||||||
} else {
|
} else {
|
||||||
tid, err := strconv.Atoi(r.URL.Path[len("/topic/delete/submit/"):])
|
tid, err := strconv.Atoi(r.URL.Path[len("/topic/delete/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -600,15 +600,15 @@ func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
|
||||||
tids = append(tids, tid)
|
tids = append(tids, tid)
|
||||||
}
|
}
|
||||||
if len(tids) == 0 {
|
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 {
|
for _, tid := range tids {
|
||||||
topic, err := c.Topics.Get(tid)
|
topic, err := c.Topics.Get(tid)
|
||||||
if err == sql.ErrNoRows {
|
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 {
|
} 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
|
// 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
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.DeleteTopic {
|
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
|
// We might be able to handle this err better
|
||||||
err = topic.Delete()
|
err = topic.Delete()
|
||||||
if err != nil {
|
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)
|
err = c.ModLogs.Create("delete", tid, "topic", user.LastIP, user.ID)
|
||||||
if err != nil {
|
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
|
// ? - 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)
|
/*_, err = stmts.createActionReply.Exec(tid,"delete",ipaddress,user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err,w,r,isJs)
|
return c.InternalErrorJSQ(err,w,r,js)
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// TODO: Do a bulk delete action hook?
|
// 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 {
|
func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
// TODO: Move this to some sort of middleware
|
// TODO: Move this to some sort of middleware
|
||||||
var tids []int
|
var tids []int
|
||||||
var isJs = false
|
js := false
|
||||||
if c.ReqIsJson(r) {
|
if c.ReqIsJson(r) {
|
||||||
if r.Body == nil {
|
if r.Body == nil {
|
||||||
return c.PreErrorJS("No request body", w, r)
|
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 {
|
if err != nil {
|
||||||
return c.PreErrorJS("We weren't able to parse your data", w, r)
|
return c.PreErrorJS("We weren't able to parse your data", w, r)
|
||||||
}
|
}
|
||||||
isJs = true
|
js = true
|
||||||
} else {
|
} else {
|
||||||
tid, err := strconv.Atoi(r.URL.Path[len("/topic/lock/submit/"):])
|
tid, err := strconv.Atoi(r.URL.Path[len("/topic/lock/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -730,15 +730,15 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
|
||||||
tids = append(tids, tid)
|
tids = append(tids, tid)
|
||||||
}
|
}
|
||||||
if len(tids) == 0 {
|
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 {
|
for _, tid := range tids {
|
||||||
topic, err := c.Topics.Get(tid)
|
topic, err := c.Topics.Get(tid)
|
||||||
if err == sql.ErrNoRows {
|
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 {
|
} 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
|
// 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
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.CloseTopic {
|
if !user.Perms.ViewTopic || !user.Perms.CloseTopic {
|
||||||
return c.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = topic.Lock()
|
err = topic.Lock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = addTopicAction("lock", topic, user)
|
err = addTopicAction("lock", topic, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Do a bulk lock action hook?
|
// 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
|
// 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 {
|
||||||
isJs := (r.PostFormValue("isJs") == "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, isJs)
|
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic, err := c.Topics.Get(tid)
|
topic, err := c.Topics.Get(tid)
|
||||||
if err == sql.ErrNoRows {
|
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 {
|
} 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
|
// 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
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.LikeItem {
|
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 {
|
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)
|
_, err = c.Users.Get(topic.CreatedBy)
|
||||||
if err != nil && err == sql.ErrNoRows {
|
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 {
|
} else if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
score := 1
|
score := 1
|
||||||
err = topic.Like(score, user.ID)
|
err = topic.Like(score, user.ID)
|
||||||
if err == c.ErrAlreadyLiked {
|
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 {
|
} 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
|
// ! 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}
|
alert := c.Alert{ActorID: user.ID, TargetUserID: topic.CreatedBy, Event: "like", ElementType: "topic", ElementID: tid, Actor: &user}
|
||||||
err = c.AddActivityAndNotifyTarget(alert)
|
err = c.AddActivityAndNotifyTarget(alert)
|
||||||
if err != nil {
|
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)
|
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
|
return rerr
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isJs {
|
if !js {
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
||||||
} else {
|
} else {
|
||||||
_, _ = w.Write(successJSONBytes)
|
_, _ = 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 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>
|
||||||
<div class="formrow">
|
<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}}
|
{{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;" />
|
<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}}
|
<label for="quick_topic_upload_files" class="formbutton add_file_button">{{lang "create_topic_add_file_button"}}</label>{{end}}
|
||||||
|
|
|
@ -9,14 +9,12 @@
|
||||||
<div id="poweredBy">
|
<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>
|
<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>
|
</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">
|
<form action="/theme/" method="post">
|
||||||
<div id="themeSelector">
|
<div id="themeSelector">
|
||||||
<select id="themeSelectorSelect" name="themeSelector" aria-label="{{lang "footer_theme_selector_aria"}}">
|
<select id="themeSelectorSelect" name="themeSelector" aria-label="{{lang "footer_theme_selector_aria"}}">{{range .Header.Themes}}
|
||||||
{{range .Header.Themes}}
|
|
||||||
{{if not .HideFromThemes}}<option val="{{.Name}}"{{if eq $.Header.Theme.Name .Name}} selected{{end}}>{{.FriendlyName}}</option>{{end}}
|
{{if not .HideFromThemes}}<option val="{{.Name}}"{{if eq $.Header.Theme.Name .Name}} selected{{end}}>{{.FriendlyName}}</option>{{end}}
|
||||||
{{end}}
|
{{end}}</select>
|
||||||
</select>
|
|
||||||
<noscript><input type="submit" /></noscript>
|
<noscript><input type="submit" /></noscript>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -24,12 +24,12 @@
|
||||||
|
|
||||||
{{if .CurrentUser.Perms.EditGroup}}
|
{{if .CurrentUser.Perms.EditGroup}}
|
||||||
<div class="colstack_item colstack_head">
|
<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>
|
||||||
<div class="colstack_item the_form">
|
<div class="colstack_item the_form">
|
||||||
<form action="/panel/groups/promotions/create/submit/{{.ID}}?s={{.CurrentUser.Session}}" method="post">
|
<form action="/panel/groups/promotions/create/submit/{{.ID}}?s={{.CurrentUser.Session}}" method="post">
|
||||||
<div class="formrow">
|
<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">
|
<div class="formitem">
|
||||||
<select name="from">
|
<select name="from">
|
||||||
{{range .Groups}}<option value="{{.ID}}">{{.Name}}</option>{{end}}
|
{{range .Groups}}<option value="{{.ID}}">{{.Name}}</option>{{end}}
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<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">
|
<div class="formitem">
|
||||||
<select name="to">
|
<select name="to">
|
||||||
{{range .Groups}}<option value="{{.ID}}">{{.Name}}</option>{{end}}
|
{{range .Groups}}<option value="{{.ID}}">{{.Name}}</option>{{end}}
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<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">
|
<div class="formitem">
|
||||||
<select name="two-way" disabled>
|
<select name="two-way" disabled>
|
||||||
<option value=1>{{lang "option_yes"}}</option>
|
<option value=1>{{lang "option_yes"}}</option>
|
||||||
|
@ -54,11 +54,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<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 class="formitem"><input name="level" type="number" value=0 /></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow form_button_row">
|
<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>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
<div class="formitem"><input name="replacement" type="text" placeholder="{{lang "panel_word_filters_create_replacement_placeholder"}}" /></div>
|
<div class="formitem"><input name="replacement" type="text" placeholder="{{lang "panel_word_filters_create_replacement_placeholder"}}" /></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<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>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
|
@ -15,7 +15,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow quick_button_row">
|
<div class="formrow quick_button_row">
|
||||||
<div class="formitem">
|
<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>
|
<button form="quick_post_form" class="formbutton" id="add_poll_button">{{lang "quick_topic.add_poll_button"}}</button>
|
||||||
{{if .CurrentUser.Perms.UploadFiles}}
|
{{if .CurrentUser.Perms.UploadFiles}}
|
||||||
<input name="upload_files" form="quick_post_form" id="upload_files" multiple type="file" class="auto_hide" />
|
<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;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.topic_list_title_block .create_topic_opt a:before {
|
.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 {
|
.topic_list_title_block .mod_opt a:before {
|
||||||
content: "{{lang "topic_list.moderate" . }}";
|
content: "{{lang "topic_list.moderate" . }}";
|
||||||
|
@ -1312,7 +1312,7 @@ input[type=checkbox]:checked + label .sel {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.topic_list_title_block .create_topic_opt a:before {
|
.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 {
|
.topic_list_title_block .mod_opt a:before {
|
||||||
content: "{{lang "topic_list.moderate_short" . }}";
|
content: "{{lang "topic_list.moderate_short" . }}";
|
||||||
|
|
Loading…
Reference in New Issue