Refactor: change number of return parameters from page functions, include error handling in wrapper

This commit is contained in:
2026-02-10 16:32:20 -07:00
parent e163224a62
commit 080f78a414
15 changed files with 497 additions and 589 deletions
+41 -49
View File
@@ -10,7 +10,6 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"net/http" "net/http"
"strconv" "strconv"
@@ -28,28 +27,27 @@ import (
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func ShowCommunity(ctxt ui.AmContext) (string, any, error) { func ShowCommunity(ctxt ui.AmContext) (string, any) {
me := ctxt.CurrentUser() me := ctxt.CurrentUser()
prefs, err := me.Prefs(ctxt.Ctx()) prefs, err := me.Prefs(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
comm := ctxt.CurrentCommunity() // set by middleware comm := ctxt.CurrentCommunity() // set by middleware
ci, err := comm.ContactInfo(ctxt.Ctx()) ci, err := comm.ContactInfo(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
host, err := comm.Host(ctxt.Ctx()) host, err := comm.Host(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
var cats []*database.Category var cats []*database.Category
if !ctxt.GlobalFlags().Get(database.GlobalFlagNoCategories) { if !ctxt.GlobalFlags().Get(database.GlobalFlagNoCategories) {
cats, err = database.AmGetCategoryHierarchy(ctxt.Ctx(), comm.CategoryId) cats, err = database.AmGetCategoryHierarchy(ctxt.Ctx(), comm.CategoryId)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
} }
var pvtAddr bool var pvtAddr bool
@@ -128,7 +126,7 @@ func ShowCommunity(ctxt ui.AmContext) (string, any, error) {
} }
ctxt.VarMap().Set("amsterdam_pageTitle", "Community Profile: "+comm.Name) ctxt.VarMap().Set("amsterdam_pageTitle", "Community Profile: "+comm.Name)
return "framed_template", "comprofile.jet", nil return "framed", "comprofile.jet"
} }
/* JoinCommunity joins a public community, or starts the process of joining a private one. /* JoinCommunity joins a public community, or starts the process of joining a private one.
@@ -137,24 +135,23 @@ func ShowCommunity(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func JoinCommunity(ctxt ui.AmContext) (string, any, error) { func JoinCommunity(ctxt ui.AmContext) (string, any) {
me := ctxt.CurrentUser() me := ctxt.CurrentUser()
comm := ctxt.CurrentCommunity() // set by middleware comm := ctxt.CurrentCommunity() // set by middleware
mbr, _, _, err := comm.Membership(ctxt.Ctx(), me) mbr, _, _, err := comm.Membership(ctxt.Ctx(), me)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
if mbr { if mbr {
// already member, this is a no-op // already member, this is a no-op
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias)
} }
if comm.TestPermission("Community.Join", me.BaseLevel) { if comm.TestPermission("Community.Join", me.BaseLevel) {
if comm.JoinKey != nil && *comm.JoinKey != "" { if comm.JoinKey != nil && *comm.JoinKey != "" {
dlg, err := ui.AmLoadDialog("join") dlg, err := ui.AmLoadDialog("join")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
dlg.SetCommunity(comm) dlg.SetCommunity(comm)
dlg.Field("cc").Value = comm.Alias dlg.Field("cc").Value = comm.Alias
@@ -163,12 +160,12 @@ func JoinCommunity(ctxt ui.AmContext) (string, any, error) {
// if get here, this is a public community, and we can join // if get here, this is a public community, and we can join
err = comm.SetMembership(ctxt.Ctx(), me, database.AmDefaultRole("Community.NewUser").Level(), false, me.Uid, ctxt.RemoteIP()) err = comm.SetMembership(ctxt.Ctx(), me, database.AmDefaultRole("Community.NewUser").Level(), false, me.Uid, ctxt.RemoteIP())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
} else { } else {
return ui.ErrorPage(ctxt, errors.New("you are not permitted to join this community")) return "error", "you are not permitted to join this community"
} }
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias)
} }
/* JoinCommunityWithKey joins a private community with a properly specified join key. /* JoinCommunityWithKey joins a private community with a properly specified join key.
@@ -177,29 +174,28 @@ func JoinCommunity(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func JoinCommunityWithKey(ctxt ui.AmContext) (string, any, error) { func JoinCommunityWithKey(ctxt ui.AmContext) (string, any) {
me := ctxt.CurrentUser() me := ctxt.CurrentUser()
comm := ctxt.CurrentCommunity() // set by middleware comm := ctxt.CurrentCommunity() // set by middleware
mbr, _, _, err := comm.Membership(ctxt.Ctx(), me) mbr, _, _, err := comm.Membership(ctxt.Ctx(), me)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
if mbr { if mbr {
// already member, this is a no-op // already member, this is a no-op
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias)
} }
if comm.TestPermission("Community.Join", me.BaseLevel) { if comm.TestPermission("Community.Join", me.BaseLevel) {
dlg, err := ui.AmLoadDialog("join") dlg, err := ui.AmLoadDialog("join")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
dlg.SetCommunity(comm) dlg.SetCommunity(comm)
dlg.LoadFromForm(ctxt) dlg.LoadFromForm(ctxt)
action := dlg.WhichButton(ctxt) action := dlg.WhichButton(ctxt)
if action == "cancel" { if action == "cancel" {
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias)
} }
if action == "join_now" { if action == "join_now" {
key := dlg.Field("key").Value key := dlg.Field("key").Value
@@ -214,11 +210,11 @@ func JoinCommunityWithKey(ctxt ui.AmContext) (string, any, error) {
if err != nil { if err != nil {
return dlg.RenderError(ctxt, fmt.Sprintf("Error joining: %v", err)) return dlg.RenderError(ctxt, fmt.Sprintf("Error joining: %v", err))
} }
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias)
} }
return dlg.RenderError(ctxt, "Unknown button pressed on join form.") return dlg.RenderError(ctxt, "Unknown button pressed on join form.")
} }
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias)
} }
/* UnjoinCommunity starts the process of unjoining a community. /* UnjoinCommunity starts the process of unjoining a community.
@@ -227,26 +223,25 @@ func JoinCommunityWithKey(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func UnjoinCommunity(ctxt ui.AmContext) (string, any, error) { func UnjoinCommunity(ctxt ui.AmContext) (string, any) {
me := ctxt.CurrentUser() me := ctxt.CurrentUser()
comm := ctxt.CurrentCommunity() // set by middleware comm := ctxt.CurrentCommunity() // set by middleware
mbr, lock, _, err := comm.Membership(ctxt.Ctx(), me) mbr, lock, _, err := comm.Membership(ctxt.Ctx(), me)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
if !mbr { if !mbr {
// not a member, just redirect to profile // not a member, just redirect to profile
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias)
} }
if lock { if lock {
ctxt.SetRC(http.StatusForbidden) ctxt.SetRC(http.StatusForbidden)
return ui.ErrorPage(ctxt, errors.New("you are not permitted to unjoin this community")) return "error", "you are not permitted to unjoin this community"
} }
ctxt.VarMap().Set("comm", comm) ctxt.VarMap().Set("comm", comm)
ctxt.VarMap().Set("amsterdam_pageTitle", "Unjoin Community") ctxt.VarMap().Set("amsterdam_pageTitle", "Unjoin Community")
return "framed_template", "unjoin.jet", nil return "framed", "unjoin.jet"
} }
/* UnjoinCommunityConfirm finishes the process of unjoining a community. /* UnjoinCommunityConfirm finishes the process of unjoining a community.
@@ -255,35 +250,34 @@ func UnjoinCommunity(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func UnjoinCommunityConfirm(ctxt ui.AmContext) (string, any, error) { func UnjoinCommunityConfirm(ctxt ui.AmContext) (string, any) {
me := ctxt.CurrentUser() me := ctxt.CurrentUser()
comm := ctxt.CurrentCommunity() // set by middleware comm := ctxt.CurrentCommunity() // set by middleware
mbr, lock, _, err := comm.Membership(ctxt.Ctx(), me) mbr, lock, _, err := comm.Membership(ctxt.Ctx(), me)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
if !mbr { if !mbr {
// not a member, just redirect to profile // not a member, just redirect to profile
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias)
} }
if lock { if lock {
ctxt.SetRC(http.StatusForbidden) ctxt.SetRC(http.StatusForbidden)
return ui.ErrorPage(ctxt, errors.New("you are not permitted to unjoin this community")) return "error", "you are not permitted to unjoin this community"
} }
if ctxt.FormFieldIsSet("cancel") { if ctxt.FormFieldIsSet("cancel") {
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias)
} }
if ctxt.FormFieldIsSet("unjoin") { if ctxt.FormFieldIsSet("unjoin") {
err = comm.SetMembership(ctxt.Ctx(), me, 0, false, me.Uid, ctxt.RemoteIP()) err = comm.SetMembership(ctxt.Ctx(), me, 0, false, me.Uid, ctxt.RemoteIP())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
ctxt.ClearCommunityContext() ctxt.ClearCommunityContext()
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias)
} }
return ui.ErrorPage(ctxt, errors.New("unknown button pressed to confirm unjoin")) return "error", "unknown button pressed to confirm unjoin"
} }
/* MemberList lists the members of the community. /* MemberList lists the members of the community.
@@ -292,9 +286,8 @@ func UnjoinCommunityConfirm(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func MemberList(ctxt ui.AmContext) (string, any, error) { func MemberList(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() // set by middleware comm := ctxt.CurrentCommunity() // set by middleware
ofs := 0 ofs := 0
p := ctxt.Parameter("ofs") p := ctxt.Parameter("ofs")
@@ -316,7 +309,7 @@ func MemberList(ctxt ui.AmContext) (string, any, error) {
listMax := int(ctxt.Globals().MaxCommunityMemberPage) listMax := int(ctxt.Globals().MaxCommunityMemberPage)
results, total, err := comm.ListMembers(ctxt.Ctx(), database.ListMembersFieldNone, database.ListMembersOperNone, "", ofs*listMax, listMax, showHidden) results, total, err := comm.ListMembers(ctxt.Ctx(), database.ListMembersFieldNone, database.ListMembersOperNone, "", ofs*listMax, listMax, showHidden)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
if total == 0 { if total == 0 {
ctxt.VarMap().Set("headerLine", "Community Members: (None)") ctxt.VarMap().Set("headerLine", "Community Members: (None)")
@@ -333,7 +326,7 @@ func MemberList(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("resultShowNext", true) ctxt.VarMap().Set("resultShowNext", true)
} }
} }
return "framed_template", "memberlist.jet", nil return "framed", "memberlist.jet"
} }
/* MemberSearch searches for members of the community. /* MemberSearch searches for members of the community.
@@ -342,9 +335,8 @@ func MemberList(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func MemberSearch(ctxt ui.AmContext) (string, any, error) { func MemberSearch(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() // set by middleware comm := ctxt.CurrentCommunity() // set by middleware
ofs, _ := ctxt.FormFieldInt("ofs") ofs, _ := ctxt.FormFieldInt("ofs")
field := ctxt.FormField("field") field := ctxt.FormField("field")
@@ -371,7 +363,7 @@ func MemberSearch(ctxt ui.AmContext) (string, any, error) {
iField = database.ListMembersFieldLastName iField = database.ListMembersFieldLastName
default: default:
ctxt.VarMap().Set("errorMessage", "invalid parameter to find") ctxt.VarMap().Set("errorMessage", "invalid parameter to find")
return "framed_template", "memberlist.jet", nil return "framed", "memberlist.jet"
} }
switch oper { switch oper {
case "st": case "st":
@@ -382,12 +374,12 @@ func MemberSearch(ctxt ui.AmContext) (string, any, error) {
iOper = database.ListMembersOperRegex iOper = database.ListMembersOperRegex
default: default:
ctxt.VarMap().Set("errorMessage", "invalid parameter to find") ctxt.VarMap().Set("errorMessage", "invalid parameter to find")
return "framed_template", "memberlist.jet", nil return "framed", "memberlist.jet"
} }
listMax := int(ctxt.Globals().MaxCommunityMemberPage) listMax := int(ctxt.Globals().MaxCommunityMemberPage)
results, total, err := comm.ListMembers(ctxt.Ctx(), iField, iOper, term, ofs*listMax, listMax, showHidden) results, total, err := comm.ListMembers(ctxt.Ctx(), iField, iOper, term, ofs*listMax, listMax, showHidden)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
if total == 0 { if total == 0 {
ctxt.VarMap().Set("headerLine", "Search Results: (None)") ctxt.VarMap().Set("headerLine", "Search Results: (None)")
@@ -404,5 +396,5 @@ func MemberSearch(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("resultShowNext", true) ctxt.VarMap().Set("resultShowNext", true)
} }
} }
return "framed_template", "memberlist.jet", nil return "framed", "memberlist.jet"
} }
+38 -49
View File
@@ -21,6 +21,7 @@ import (
"git.erbosoft.com/amy/amsterdam/database" "git.erbosoft.com/amy/amsterdam/database"
"git.erbosoft.com/amy/amsterdam/ui" "git.erbosoft.com/amy/amsterdam/ui"
"git.erbosoft.com/amy/amsterdam/util" "git.erbosoft.com/amy/amsterdam/util"
"github.com/labstack/echo/v4"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@@ -30,13 +31,11 @@ import (
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func CommunityAdminMenu(ctxt ui.AmContext) (string, any, error) { func CommunityAdminMenu(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() // set by middleware comm := ctxt.CurrentCommunity() // set by middleware
if !comm.TestPermission("Community.ShowAdmin", ctxt.EffectiveLevel()) { if !comm.TestPermission("Community.ShowAdmin", ctxt.EffectiveLevel()) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOACCESS
return ui.ErrorPage(ctxt, errors.New("you are not permitted to access this page"))
} }
menu := ui.AmMenu("communityadmin") menu := ui.AmMenu("communityadmin")
defs := make(map[string]bool) defs := make(map[string]bool)
@@ -46,7 +45,7 @@ func CommunityAdminMenu(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("menu", menu.FilterCommunity(comm)) ctxt.VarMap().Set("menu", menu.FilterCommunity(comm))
ctxt.VarMap().Set("defs", defs) ctxt.VarMap().Set("defs", defs)
ctxt.VarMap().Set("amsterdam_pageTitle", menu.Title+" - "+comm.Name) ctxt.VarMap().Set("amsterdam_pageTitle", menu.Title+" - "+comm.Name)
return "framed_template", "menu.jet", nil return "framed", "menu.jet"
} }
// setupCommunityProfileDialog sets up fields in the Community Profile dialog. // setupCommunityProfileDialog sets up fields in the Community Profile dialog.
@@ -79,22 +78,20 @@ func communityLogoURL(ci *database.ContactInfo) string {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func CommunityProfileForm(ctxt ui.AmContext) (string, any, error) { func CommunityProfileForm(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() // set by middleware comm := ctxt.CurrentCommunity() // set by middleware
if !comm.TestPermission("Community.Write", ctxt.EffectiveLevel()) { if !comm.TestPermission("Community.Write", ctxt.EffectiveLevel()) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOACCESS
return ui.ErrorPage(ctxt, errors.New("you are not permitted to access this page"))
} }
var ci *database.ContactInfo var ci *database.ContactInfo
ci, err := comm.ContactInfo(ctxt.Ctx()) ci, err := comm.ContactInfo(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
flags, err := comm.Flags(ctxt.Ctx()) flags, err := comm.Flags(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
dlg, err := ui.AmLoadDialog("commprofile") dlg, err := ui.AmLoadDialog("commprofile")
if err == nil { if err == nil {
@@ -136,7 +133,7 @@ func CommunityProfileForm(ctxt ui.AmContext) (string, any, error) {
dlg.Field("pic_in_post").SetChecked(flags.Get(database.CommunityFlagPicturesInPosts)) dlg.Field("pic_in_post").SetChecked(flags.Get(database.CommunityFlagPicturesInPosts))
return dlg.Render(ctxt) return dlg.Render(ctxt)
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
// validateJoinKey is an extra validation step for the join key. // validateJoinKey is an extra validation step for the join key.
@@ -157,13 +154,11 @@ func validateJoinKey(dlg *ui.Dialog) error {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func EditCommunityProfile(ctxt ui.AmContext) (string, any, error) { func EditCommunityProfile(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() // set by middleware comm := ctxt.CurrentCommunity() // set by middleware
if !comm.TestPermission("Community.Write", ctxt.EffectiveLevel()) { if !comm.TestPermission("Community.Write", ctxt.EffectiveLevel()) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOACCESS
return ui.ErrorPage(ctxt, errors.New("you are not permitted to access this page"))
} }
dlg, err := ui.AmLoadDialog("commprofile") dlg, err := ui.AmLoadDialog("commprofile")
if err == nil { if err == nil {
@@ -172,7 +167,7 @@ func EditCommunityProfile(ctxt ui.AmContext) (string, any, error) {
action := dlg.WhichButton(ctxt) action := dlg.WhichButton(ctxt)
if action == "cancel" { if action == "cancel" {
return "redirect", fmt.Sprintf("/comm/%s/admin", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/admin", comm.Alias)
} }
if action == "update" { if action == "update" {
err = dlg.Validate() err = dlg.Validate()
@@ -191,7 +186,7 @@ func EditCommunityProfile(ctxt ui.AmContext) (string, any, error) {
var flags *util.OptionSet var flags *util.OptionSet
flags, err = comm.Flags(ctxt.Ctx()) flags, err = comm.Flags(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
nci := ci.Clone() nci := ci.Clone()
nci.URL = dlg.Field("url").ValPtr() nci.URL = dlg.Field("url").ValPtr()
@@ -237,12 +232,12 @@ func EditCommunityProfile(ctxt ui.AmContext) (string, any, error) {
ctxt.ClearCommunityContext() ctxt.ClearCommunityContext()
return dlg.RenderError(ctxt, err.Error()) return dlg.RenderError(ctxt, err.Error())
} else { } else {
return "redirect", fmt.Sprintf("/comm/%s/admin", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/admin", comm.Alias)
} }
} }
return dlg.RenderError(ctxt, "No known button click on POST to community profile.") return dlg.RenderError(ctxt, "No known button click on POST to community profile.")
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
/* CommunityLogoForm renders the form for changing the community logo. /* CommunityLogoForm renders the form for changing the community logo.
@@ -251,13 +246,11 @@ func EditCommunityProfile(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func CommunityLogoForm(ctxt ui.AmContext) (string, any, error) { func CommunityLogoForm(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() // set by middleware comm := ctxt.CurrentCommunity() // set by middleware
if !comm.TestPermission("Community.Write", ctxt.EffectiveLevel()) { if !comm.TestPermission("Community.Write", ctxt.EffectiveLevel()) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOACCESS
return ui.ErrorPage(ctxt, errors.New("you are not permitted to access this page"))
} }
ci, err := comm.ContactInfo(ctxt.Ctx()) ci, err := comm.ContactInfo(ctxt.Ctx())
if err == nil { if err == nil {
@@ -265,9 +258,9 @@ func CommunityLogoForm(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("commAlias", comm.Alias) ctxt.VarMap().Set("commAlias", comm.Alias)
ctxt.VarMap().Set("logo_url", communityLogoURL(ci)) ctxt.VarMap().Set("logo_url", communityLogoURL(ci))
ctxt.VarMap().Set("amsterdam_pageTitle", "Upload Community Logo: "+comm.Name) ctxt.VarMap().Set("amsterdam_pageTitle", "Upload Community Logo: "+comm.Name)
return "framed_template", "logo_upload.jet", nil return "framed", "logo_upload.jet"
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
/* EditCommunityLogo handles setting the community logo. /* EditCommunityLogo handles setting the community logo.
@@ -278,18 +271,17 @@ func CommunityLogoForm(ctxt ui.AmContext) (string, any, error) {
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status. * Standard Go error status.
*/ */
func EditCommunityLogo(ctxt ui.AmContext) (string, any, error) { func EditCommunityLogo(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() // set by middleware comm := ctxt.CurrentCommunity() // set by middleware
if !comm.TestPermission("Community.Write", ctxt.EffectiveLevel()) { if !comm.TestPermission("Community.Write", ctxt.EffectiveLevel()) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOACCESS
return ui.ErrorPage(ctxt, errors.New("you are not permitted to access this page"))
} }
ci, err := comm.ContactInfo(ctxt.Ctx()) ci, err := comm.ContactInfo(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
if ctxt.FormFieldIsSet("cancel") { if ctxt.FormFieldIsSet("cancel") {
return "redirect", "/comm/" + comm.Alias + "/admin/profile", nil return "redirect", "/comm/" + comm.Alias + "/admin/profile"
} }
if ctxt.FormFieldIsSet("upload") { if ctxt.FormFieldIsSet("upload") {
file, err := ctxt.FormFile("thepic") file, err := ctxt.FormFile("thepic")
@@ -309,7 +301,7 @@ func EditCommunityLogo(ctxt ui.AmContext) (string, any, error) {
err = comm.TouchUpdate(ctxt.Ctx()) err = comm.TouchUpdate(ctxt.Ctx())
} }
if err == nil { if err == nil {
return "redirect", "/comm/" + comm.Alias + "/admin/profile", nil return "redirect", "/comm/" + comm.Alias + "/admin/profile"
} }
} }
} }
@@ -319,19 +311,19 @@ func EditCommunityLogo(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("commAlias", comm.Alias) ctxt.VarMap().Set("commAlias", comm.Alias)
ctxt.VarMap().Set("logo_url", communityLogoURL(ci)) ctxt.VarMap().Set("logo_url", communityLogoURL(ci))
ctxt.VarMap().Set("amsterdam_pageTitle", "Upload Community Logo: "+comm.Name) ctxt.VarMap().Set("amsterdam_pageTitle", "Upload Community Logo: "+comm.Name)
return "framed_template", "logo_upload.jet", nil return "framed", "logo_upload.jet"
} }
if ctxt.FormFieldIsSet("remove") { if ctxt.FormFieldIsSet("remove") {
purl := ci.PhotoURL purl := ci.PhotoURL
happy := false happy := false
if purl == nil || *purl == "" { if purl == nil || *purl == "" {
// this is a no-op // this is a no-op
return "redirect", "/comm/" + comm.Alias + "/admin/profile", nil return "redirect", "/comm/" + comm.Alias + "/admin/profile"
} }
if strings.HasPrefix(*purl, "/img/store/") { if strings.HasPrefix(*purl, "/img/store/") {
id, err := strconv.Atoi((*purl)[11:]) id, err := strconv.Atoi((*purl)[11:])
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
defer func() { defer func() {
if happy { if happy {
@@ -347,12 +339,12 @@ func EditCommunityLogo(ctxt ui.AmContext) (string, any, error) {
ci.PhotoURL = nil ci.PhotoURL = nil
_, err := ci.Save(ctxt.Ctx()) _, err := ci.Save(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
happy = true happy = true
return "redirect", "/comm/" + comm.Alias + "/admin/profile", nil return "redirect", "/comm/" + comm.Alias + "/admin/profile"
} }
return ui.ErrorPage(ctxt, errors.New("invalid button detected in logo upload")) return "error", "invalid button detected in logo upload"
} }
/* CreateCommunityForm renders the form for creating a new community. /* CreateCommunityForm renders the form for creating a new community.
@@ -363,11 +355,10 @@ func EditCommunityLogo(ctxt ui.AmContext) (string, any, error) {
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status. * Standard Go error status.
*/ */
func CreateCommunityForm(ctxt ui.AmContext) (string, any, error) { func CreateCommunityForm(ctxt ui.AmContext) (string, any) {
user := ctxt.CurrentUser() user := ctxt.CurrentUser()
if user.BaseLevel < uint16(ctxt.Globals().CommunityCreateLevel) { if user.BaseLevel < uint16(ctxt.Globals().CommunityCreateLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", echo.NewHTTPError(http.StatusForbidden, "you are not permitted to create a community")
return ui.ErrorPage(ctxt, errors.New("you are not permitted to create a community"))
} }
dlg, err := ui.AmLoadDialog("create_comm") dlg, err := ui.AmLoadDialog("create_comm")
if err == nil { if err == nil {
@@ -375,7 +366,7 @@ func CreateCommunityForm(ctxt ui.AmContext) (string, any, error) {
dlg.Field("country").Value = "US" dlg.Field("country").Value = "US"
return dlg.Render(ctxt) return dlg.Render(ctxt)
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
/* CreateCommunity creates a new community. /* CreateCommunity creates a new community.
@@ -384,20 +375,18 @@ func CreateCommunityForm(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func CreateCommunity(ctxt ui.AmContext) (string, any, error) { func CreateCommunity(ctxt ui.AmContext) (string, any) {
user := ctxt.CurrentUser() user := ctxt.CurrentUser()
if user.BaseLevel < uint16(ctxt.Globals().CommunityCreateLevel) { if user.BaseLevel < uint16(ctxt.Globals().CommunityCreateLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", echo.NewHTTPError(http.StatusForbidden, "you are not permitted to create a community")
return ui.ErrorPage(ctxt, errors.New("you are not permitted to create a community"))
} }
dlg, err := ui.AmLoadDialog("create_comm") dlg, err := ui.AmLoadDialog("create_comm")
if err == nil { if err == nil {
dlg.LoadFromForm(ctxt) dlg.LoadFromForm(ctxt)
action := dlg.WhichButton(ctxt) action := dlg.WhichButton(ctxt)
if action == "cancel" { if action == "cancel" {
return "redirect", "/", nil return "redirect", "/"
} }
if action == "create" { if action == "create" {
err = dlg.Validate() err = dlg.Validate()
@@ -451,9 +440,9 @@ func CreateCommunity(ctxt ui.AmContext) (string, any, error) {
return dlg.RenderError(ctxt, err.Error()) return dlg.RenderError(ctxt, err.Error())
} }
// new community is now created! redirect to the new profile // new community is now created! redirect to the new profile
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias)
} }
return dlg.RenderError(ctxt, "No known button click on POST to community creation.") return dlg.RenderError(ctxt, "No known button click on POST to community creation.")
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
+54 -68
View File
@@ -12,7 +12,6 @@ package main
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"net/http" "net/http"
"reflect" "reflect"
@@ -24,6 +23,7 @@ import (
"git.erbosoft.com/amy/amsterdam/htmlcheck" "git.erbosoft.com/amy/amsterdam/htmlcheck"
"git.erbosoft.com/amy/amsterdam/ui" "git.erbosoft.com/amy/amsterdam/ui"
"github.com/CloudyKit/jet/v6" "github.com/CloudyKit/jet/v6"
"github.com/labstack/echo/v4"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@@ -35,7 +35,7 @@ import (
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status. * Standard Go error status.
*/ */
func Conferences(ctxt ui.AmContext) (string, any, error) { func Conferences(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
ctxt.VarMap().Set("commName", comm.Name) ctxt.VarMap().Set("commName", comm.Name)
ctxt.VarMap().Set("commAlias", comm.Alias) ctxt.VarMap().Set("commAlias", comm.Alias)
@@ -43,7 +43,7 @@ func Conferences(ctxt ui.AmContext) (string, any, error) {
clist, err := database.AmGetCommunityConferences(ctxt.Ctx(), comm.Id, clist, err := database.AmGetCommunityConferences(ctxt.Ctx(), comm.Id,
comm.TestPermission("Community.ShowHiddenObjects", ctxt.EffectiveLevel())) comm.TestPermission("Community.ShowHiddenObjects", ctxt.EffectiveLevel()))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
ctxt.VarMap().Set("conferences", clist) ctxt.VarMap().Set("conferences", clist)
if len(clist) > 0 { if len(clist) > 0 {
@@ -51,7 +51,7 @@ func Conferences(ctxt ui.AmContext) (string, any, error) {
for i, conf := range clist { for i, conf := range clist {
msgCount, err := conf.UnreadMessages(ctxt.Ctx(), ctxt.CurrentUser()) msgCount, err := conf.UnreadMessages(ctxt.Ctx(), ctxt.CurrentUser())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
newflag[i] = msgCount > 0 newflag[i] = msgCount > 0
} }
@@ -59,7 +59,7 @@ func Conferences(ctxt ui.AmContext) (string, any, error) {
} }
ctxt.VarMap().Set("canCreate", comm.TestPermission("Community.Create", ctxt.EffectiveLevel())) ctxt.VarMap().Set("canCreate", comm.TestPermission("Community.Create", ctxt.EffectiveLevel()))
ctxt.VarMap().Set("canManage", comm.TestPermission("Community.Create", ctxt.EffectiveLevel())) ctxt.VarMap().Set("canManage", comm.TestPermission("Community.Create", ctxt.EffectiveLevel()))
return "framed_template", "conflist.jet", err return "framed", "conflist.jet"
} }
/* Topics displays the list of topics in a conference. /* Topics displays the list of topics in a conference.
@@ -68,19 +68,17 @@ func Conferences(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func Topics(ctxt ui.AmContext) (string, any, error) { func Topics(ctxt ui.AmContext) (string, any) {
prefs, err := ctxt.CurrentUser().Prefs(ctxt.Ctx()) prefs, err := ctxt.CurrentUser().Prefs(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
if !conf.TestPermission("Conference.Read", myLevel) { if !conf.TestPermission("Conference.Read", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", echo.NewHTTPError(http.StatusForbidden, "you are not permitted to read this conference")
return ui.ErrorPage(ctxt, errors.New("you are not permitted to read this conference"))
} }
// Get view and sort parameters from query, session, or defaults. Store to session. // Get view and sort parameters from query, session, or defaults. Store to session.
@@ -109,14 +107,14 @@ func Topics(ctxt ui.AmContext) (string, any, error) {
topics, err := database.AmListTopics(ctxt.Ctx(), conf.ConfId, ctxt.CurrentUserId(), view, sort, false) topics, err := database.AmListTopics(ctxt.Ctx(), conf.ConfId, ctxt.CurrentUserId(), view, sort, false)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
var hotlistTest bool = false var hotlistTest bool = false
if !ctxt.CurrentUser().IsAnon { if !ctxt.CurrentUser().IsAnon {
hotlistTest, err = database.AmIsInHotlist(ctxt.Ctx(), ctxt.CurrentUser(), comm.Id, conf.ConfId) hotlistTest, err = database.AmIsInHotlist(ctxt.Ctx(), ctxt.CurrentUser(), comm.Id, conf.ConfId)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
} }
@@ -152,7 +150,7 @@ func Topics(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("topics", topics) ctxt.VarMap().Set("topics", topics)
ctxt.VarMap().Set("formattedDate", fdate) ctxt.VarMap().Set("formattedDate", fdate)
ctxt.VarMap().Set("amsterdam_pageTitle", "Topics in "+conf.Name) ctxt.VarMap().Set("amsterdam_pageTitle", "Topics in "+conf.Name)
return "framed_template", "topiclist.jet", nil return "framed", "topiclist.jet"
} }
/* NewTopicForm displays the form for creating a new topic. /* NewTopicForm displays the form for creating a new topic.
@@ -161,27 +159,25 @@ func Topics(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func NewTopicForm(ctxt ui.AmContext) (string, any, error) { func NewTopicForm(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
if !conf.TestPermission("Conference.Create", myLevel) { if !conf.TestPermission("Conference.Create", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", echo.NewHTTPError(http.StatusForbidden, "you are not permitted to create topics in this conference")
return ui.ErrorPage(ctxt, errors.New("you are not permitted to create topics in this conference"))
} }
ctxt.VarMap().Set("conferenceName", conf.Name) ctxt.VarMap().Set("conferenceName", conf.Name)
ctxt.VarMap().Set("urlStem", fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, ctxt.GetScratch("currentAlias"))) ctxt.VarMap().Set("urlStem", fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, ctxt.GetScratch("currentAlias")))
ctxt.VarMap().Set("topicName", "") ctxt.VarMap().Set("topicName", "")
pseud, err := conf.DefaultPseud(ctxt.Ctx(), ctxt.CurrentUser()) pseud, err := conf.DefaultPseud(ctxt.Ctx(), ctxt.CurrentUser())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
ctxt.VarMap().Set("pseud", pseud) ctxt.VarMap().Set("pseud", pseud)
ctxt.VarMap().Set("pb", "") ctxt.VarMap().Set("pb", "")
ctxt.VarMap().Set("amsterdam_pageTitle", "Create New Topic") ctxt.VarMap().Set("amsterdam_pageTitle", "Create New Topic")
return "framed_template", "new_topic.jet", nil return "framed", "new_topic.jet"
} }
/* NewTopic creates a new topic and posts the initial message. /* NewTopic creates a new topic and posts the initial message.
@@ -190,26 +186,24 @@ func NewTopicForm(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func NewTopic(ctxt ui.AmContext) (string, any, error) { func NewTopic(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
if !conf.TestPermission("Conference.Create", myLevel) { if !conf.TestPermission("Conference.Create", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", echo.NewHTTPError(http.StatusForbidden, "you are not permitted to create topics in this conference")
return ui.ErrorPage(ctxt, errors.New("you are not permitted to create topics in this conference"))
} }
urlStem := fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, ctxt.GetScratch("currentAlias")) urlStem := fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, ctxt.GetScratch("currentAlias"))
if ctxt.FormFieldIsSet("cancel") { if ctxt.FormFieldIsSet("cancel") {
return "redirect", urlStem, nil return "redirect", urlStem
} }
if ctxt.FormFieldIsSet("preview") { if ctxt.FormFieldIsSet("preview") {
// start by escaping the title // start by escaping the title
checker, err := htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "escaper") checker, err := htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "escaper")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
checker.Append(ctxt.FormField("title")) checker.Append(ctxt.FormField("title"))
checker.Finish() checker.Finish()
@@ -234,7 +228,7 @@ func NewTopic(ctxt ui.AmContext) (string, any, error) {
// run the preview // run the preview
checker, err = htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "preview") checker, err = htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "preview")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
checker.SetContext("PostLinkDecoderContext", database.AmCreatePostLinkContext(comm.Alias, ctxt.URLParam("cid"), conf.TopTopic+1)) checker.SetContext("PostLinkDecoderContext", database.AmCreatePostLinkContext(comm.Alias, ctxt.URLParam("cid"), conf.TopTopic+1))
checker.Append(postdata) checker.Append(postdata)
@@ -250,13 +244,13 @@ func NewTopic(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("conferenceName", conf.Name) ctxt.VarMap().Set("conferenceName", conf.Name)
ctxt.VarMap().Set("urlStem", urlStem) ctxt.VarMap().Set("urlStem", urlStem)
ctxt.VarMap().Set("amsterdam_pageTitle", "Preview New Topic") ctxt.VarMap().Set("amsterdam_pageTitle", "Preview New Topic")
return "framed_template", "new_topic.jet", nil return "framed", "new_topic.jet"
} }
if ctxt.FormFieldIsSet("post1") { if ctxt.FormFieldIsSet("post1") {
// start by checking the title and pseud // start by checking the title and pseud
checker, err := htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "post-pseud") checker, err := htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "post-pseud")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
checker.Append(ctxt.FormField("title")) checker.Append(ctxt.FormField("title"))
checker.Finish() checker.Finish()
@@ -269,7 +263,7 @@ func NewTopic(ctxt ui.AmContext) (string, any, error) {
// now check the post data itself // now check the post data itself
checker, err = htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "post-body") checker, err = htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "post-body")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
checker.SetContext("PostLinkDecoderContext", database.AmCreatePostLinkContext(comm.Alias, ctxt.URLParam("cid"), conf.TopTopic+1)) checker.SetContext("PostLinkDecoderContext", database.AmCreatePostLinkContext(comm.Alias, ctxt.URLParam("cid"), conf.TopTopic+1))
checker.Append(ctxt.FormField("pb")) checker.Append(ctxt.FormField("pb"))
@@ -280,26 +274,26 @@ func NewTopic(ctxt ui.AmContext) (string, any, error) {
// Add the topic! // Add the topic!
topic, err := database.AmNewTopic(ctxt.Ctx(), conf, ctxt.CurrentUser(), topicName, zeroPostPseud, zeroPost, int32(lines), ctxt.RemoteIP()) topic, err := database.AmNewTopic(ctxt.Ctx(), conf, ctxt.CurrentUser(), topicName, zeroPostPseud, zeroPost, int32(lines), ctxt.RemoteIP())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
if !ctxt.FormFieldIsSet("attach") { if !ctxt.FormFieldIsSet("attach") {
return "redirect", urlStem, nil // no attachment - just redisplay topic list return "redirect", urlStem // no attachment - just redisplay topic list
} }
post, err := topic.GetPost(ctxt.Ctx(), 0) // get the initial post in the new topic post, err := topic.GetPost(ctxt.Ctx(), 0) // get the initial post in the new topic
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
// go upload the attachment // go upload the attachment
ctxt.VarMap().Set("target", urlStem) ctxt.VarMap().Set("target", urlStem)
ctxt.VarMap().Set("post", post.PostId) ctxt.VarMap().Set("post", post.PostId)
ctxt.VarMap().Set("amsterdam_pageTitle", "Upload Attachment") ctxt.VarMap().Set("amsterdam_pageTitle", "Upload Attachment")
return "framed_template", "attachment_upload.jet", nil return "framed_template", "attachment_upload.jet"
} }
return ui.ErrorPage(ctxt, errors.New("invalid button clicked on form")) return "error", "invalid button clicked on form"
} }
/* breakRange breaks up a post range into two elements. /* breakRange breaks up a post range into two elements.
@@ -434,9 +428,8 @@ func templateBozo(args jet.Arguments) reflect.Value {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func ReadPosts(ctxt ui.AmContext) (string, any, error) { func ReadPosts(ctxt ui.AmContext) (string, any) {
// Extract the traverser first, so we can unclear it in background tasks. // Extract the traverser first, so we can unclear it in background tasks.
var traverser ui.TopicTraverser = nil var traverser ui.TopicTraverser = nil
if ctxt.IsSession("topic.traverser") { if ctxt.IsSession("topic.traverser") {
@@ -466,7 +459,7 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
// Get user prefs. // Get user prefs.
prefs, err := ctxt.CurrentUser().Prefs(ctxt.Ctx()) prefs, err := ctxt.CurrentUser().Prefs(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
// Locate community, conference, and topic. // Locate community, conference, and topic.
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
@@ -478,21 +471,18 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
// Determine the range of posts to display. The "pin" is the post number after which we display the horizontal line separating old and new posts. // Determine the range of posts to display. The "pin" is the post number after which we display the horizontal line separating old and new posts.
lastRead, err := topic.GetLastRead(ctxt.Ctx(), ctxt.CurrentUser()) lastRead, err := topic.GetLastRead(ctxt.Ctx(), ctxt.CurrentUser())
if err != nil { if err != nil {
ctxt.SetRC(http.StatusNotFound) return "error", echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("posts not found in topic %d - %v", topic.Number, err))
return ui.ErrorPage(ctxt, fmt.Errorf("posts not found in topic %d - %v", topic.Number, err))
} }
postRange := make([]int32, 2) postRange := make([]int32, 2)
var pin int32 = -1 var pin int32 = -1
resetLastRead := false resetLastRead := false
if ctxt.HasParameter("r") { if ctxt.HasParameter("r") {
if err := breakRange(topic, postRange, ctxt.Parameter("r"), ","); err != nil { if err := breakRange(topic, postRange, ctxt.Parameter("r"), ","); err != nil {
ctxt.SetRC(http.StatusNotFound) return "error", echo.NewHTTPError(http.StatusNotFound).SetInternal(err)
return ui.ErrorPage(ctxt, err)
} }
} else if ctxt.HasParameter("rgo") { } else if ctxt.HasParameter("rgo") {
if err := breakRange(topic, postRange, ctxt.Parameter("rgo"), "-"); err != nil { if err := breakRange(topic, postRange, ctxt.Parameter("rgo"), "-"); err != nil {
ctxt.SetRC(http.StatusNotFound) return "error", echo.NewHTTPError(http.StatusNotFound).SetInternal(err)
return ui.ErrorPage(ctxt, err)
} }
} else { } else {
postRange[0] = lastRead + 1 postRange[0] = lastRead + 1
@@ -515,7 +505,7 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
// Load the actual posts. // Load the actual posts.
posts, err := database.AmGetPostRange(ctxt.Ctx(), topic, postRange[0], postRange[1]) posts, err := database.AmGetPostRange(ctxt.Ctx(), topic, postRange[0], postRange[1])
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, fmt.Errorf("internal error getting posts <%d:%d-%d> - %v", topic.Number, postRange[0], postRange[1], err)) return "error", fmt.Sprintf("internal error getting posts <%d:%d-%d> - %v", topic.Number, postRange[0], postRange[1], err)
} }
// Determine other required data. // Determine other required data.
@@ -547,7 +537,7 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
// Set the user's pseud. // Set the user's pseud.
pseud, err := conf.DefaultPseud(ctxt.Ctx(), ctxt.CurrentUser()) pseud, err := conf.DefaultPseud(ctxt.Ctx(), ctxt.CurrentUser())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
ctxt.VarMap().Set("pseud", pseud) ctxt.VarMap().Set("pseud", pseud)
@@ -572,7 +562,7 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
if nbozo >= 0 { if nbozo >= 0 {
err = topic.SetBozo(ctxt.Ctx(), ctxt.CurrentUser(), posts[0].CreatorUid, nbozo != 0) err = topic.SetBozo(ctxt.Ctx(), ctxt.CurrentUser(), posts[0].CreatorUid, nbozo != 0)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
} }
isMyPost := (posts[0].CreatorUid == ctxt.CurrentUserId()) && !ctxt.CurrentUser().IsAnon isMyPost := (posts[0].CreatorUid == ctxt.CurrentUserId()) && !ctxt.CurrentUser().IsAnon
@@ -632,7 +622,7 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
topic.SetLastRead(ctx, user, topic.TopMessage) topic.SetLastRead(ctx, user, topic.TopMessage)
}) })
} }
return "framed_template", "posts.jet", nil return "framed", "posts.jet"
} }
/* PostInTopic adds a new post to a topic. /* PostInTopic adds a new post to a topic.
@@ -641,9 +631,8 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func PostInTopic(ctxt ui.AmContext) (string, any, error) { func PostInTopic(ctxt ui.AmContext) (string, any) {
// Locate community, conference, and topic. // Locate community, conference, and topic.
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
@@ -653,28 +642,25 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
urlStem := fmt.Sprintf("/comm/%s/conf/%s/r/%d", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number) urlStem := fmt.Sprintf("/comm/%s/conf/%s/r/%d", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number)
if ctxt.FormFieldIsSet("cancel") { if ctxt.FormFieldIsSet("cancel") {
return "redirect", urlStem, nil return "redirect", urlStem
} }
if !conf.TestPermission("Conference.Post", level) { if !conf.TestPermission("Conference.Post", level) {
ctxt.SetRC(http.StatusForbidden) return "error", echo.NewHTTPError(http.StatusForbidden, "you do not have permission to post in this conference")
return ui.ErrorPage(ctxt, errors.New("you do not have permission to post in this conference"))
} }
if topic.Frozen && !conf.TestPermission("Conference.Hide", level) { if topic.Frozen && !conf.TestPermission("Conference.Hide", level) {
ctxt.SetRC(http.StatusForbidden) return "error", echo.NewHTTPError(http.StatusForbidden, "this topic is frozen, and you do not have permission to post to it")
return ui.ErrorPage(ctxt, errors.New("this topic is frozen, and you do not have permission to post to it"))
} }
if topic.Archived && !conf.TestPermission("Conference.Hide", level) { if topic.Archived && !conf.TestPermission("Conference.Hide", level) {
ctxt.SetRC(http.StatusForbidden) return "error", echo.NewHTTPError(http.StatusForbidden, "this topic is archived, and you do not have permission to post to it")
return ui.ErrorPage(ctxt, errors.New("this topic is archived, and you do not have permission to post to it"))
} }
// Set the escaped version of the text into the varmap, because it'll be needed if we do anything other than redirect. // Set the escaped version of the text into the varmap, because it'll be needed if we do anything other than redirect.
checker, err := htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "escaper") checker, err := htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "escaper")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
checker.Append(ctxt.FormField("pseud")) checker.Append(ctxt.FormField("pseud"))
checker.Finish() checker.Finish()
@@ -700,7 +686,7 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
// Preview the post. // Preview the post.
checker, err = htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "preview") checker, err = htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "preview")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
checker.SetContext("PostLinkDecoderContext", database.AmCreatePostLinkContext(comm.Alias, ctxt.URLParam("cid"), topic.Number)) checker.SetContext("PostLinkDecoderContext", database.AmCreatePostLinkContext(comm.Alias, ctxt.URLParam("cid"), topic.Number))
checker.Append(postdata) checker.Append(postdata)
@@ -713,7 +699,7 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("maxPost", ctxt.FormField("xp")) ctxt.VarMap().Set("maxPost", ctxt.FormField("xp"))
ctxt.VarMap().Set("urlStem", urlStem) ctxt.VarMap().Set("urlStem", urlStem)
ctxt.VarMap().Set("amsterdam_pageTitle", "Previewing Message") ctxt.VarMap().Set("amsterdam_pageTitle", "Previewing Message")
return "framed_template", "preview_post.jet", nil return "framed", "preview_post.jet"
} }
// Figure out which URL to return to once this post is made. // Figure out which URL to return to once this post is made.
var returnURL string var returnURL string
@@ -724,20 +710,20 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
} else if ctxt.FormFieldIsSet("posttopics") { } else if ctxt.FormFieldIsSet("posttopics") {
returnURL = fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, ctxt.GetScratch("currentAlias")) returnURL = fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, ctxt.GetScratch("currentAlias"))
} else { } else {
return ui.ErrorPage(ctxt, errors.New("unknown post button")) return "error", "unknown post button"
} }
// Check for slippage. // Check for slippage.
maxPost, err := ctxt.FormFieldInt("xp") maxPost, err := ctxt.FormFieldInt("xp")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
if int32(maxPost) < topic.TopMessage { if int32(maxPost) < topic.TopMessage {
// Slippage detected! Display the slipped posts and another post box. // Slippage detected! Display the slipped posts and another post box.
// Start by getting the slipped posts. // Start by getting the slipped posts.
posts, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(maxPost), topic.TopMessage) posts, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(maxPost), topic.TopMessage)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
plc := database.AmCreatePostLinkContext("", ctxt.GetScratch("currentAlias").(string), topic.Number) plc := database.AmCreatePostLinkContext("", ctxt.GetScratch("currentAlias").(string), topic.Number)
@@ -757,12 +743,12 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("topicName", topic.Name) ctxt.VarMap().Set("topicName", topic.Name)
ctxt.VarMap().Set("amsterdam_pageTitle", "Slippage or Double-Click Detected") ctxt.VarMap().Set("amsterdam_pageTitle", "Slippage or Double-Click Detected")
return "framed_template", "slippage.jet", nil return "framed", "slippage.jet"
} }
// if we get here, we are posting - start by checking the title and pseud // if we get here, we are posting - start by checking the title and pseud
checker, err = htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "post-pseud") checker, err = htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "post-pseud")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
checker.Append(ctxt.FormField("pseud")) checker.Append(ctxt.FormField("pseud"))
checker.Finish() checker.Finish()
@@ -771,7 +757,7 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
// now check the post data itself // now check the post data itself
checker, err = htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "post-body") checker, err = htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "post-body")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
checker.SetContext("PostLinkDecoderContext", database.AmCreatePostLinkContext(comm.Alias, ctxt.URLParam("cid"), topic.Number)) checker.SetContext("PostLinkDecoderContext", database.AmCreatePostLinkContext(comm.Alias, ctxt.URLParam("cid"), topic.Number))
checker.Append(ctxt.FormField("pb")) checker.Append(ctxt.FormField("pb"))
@@ -782,7 +768,7 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
// Add the post! // Add the post!
hdr, err := database.AmNewPost(ctxt.Ctx(), conf, topic, ctxt.CurrentUser(), postPseud, postText, int32(lines), ctxt.RemoteIP()) hdr, err := database.AmNewPost(ctxt.Ctx(), conf, topic, ctxt.CurrentUser(), postPseud, postText, int32(lines), ctxt.RemoteIP())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
// Check who's subscribed to this topic. // Check who's subscribed to this topic.
@@ -800,12 +786,12 @@ func PostInTopic(ctxt ui.AmContext) (string, any, error) {
} }
if !ctxt.FormFieldIsSet("attach") { if !ctxt.FormFieldIsSet("attach") {
return "redirect", returnURL, nil // no attachment - just bounce directly to the destination return "redirect", returnURL // no attachment - just bounce directly to the destination
} }
// go upload the attachment // go upload the attachment
ctxt.VarMap().Set("target", returnURL) ctxt.VarMap().Set("target", returnURL)
ctxt.VarMap().Set("post", hdr.PostId) ctxt.VarMap().Set("post", hdr.PostId)
ctxt.VarMap().Set("amsterdam_pageTitle", "Upload Attachment") ctxt.VarMap().Set("amsterdam_pageTitle", "Upload Attachment")
return "framed_template", "attachment_upload.jet", nil return "framed", "attachment_upload.jet"
} }
+119 -152
View File
@@ -23,9 +23,13 @@ import (
"git.erbosoft.com/amy/amsterdam/database" "git.erbosoft.com/amy/amsterdam/database"
"git.erbosoft.com/amy/amsterdam/email" "git.erbosoft.com/amy/amsterdam/email"
"git.erbosoft.com/amy/amsterdam/ui" "git.erbosoft.com/amy/amsterdam/ui"
"github.com/labstack/echo/v4"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
// EPOSTREF is the internal error for post references.
var EPOSTREF error = errors.New("internal error getting post reference")
// slurpFile reads the contrents of a multipart.File into memory. // slurpFile reads the contrents of a multipart.File into memory.
func slurpFile(file *multipart.FileHeader) ([]byte, error) { func slurpFile(file *multipart.FileHeader) ([]byte, error) {
f, err := file.Open() f, err := file.Open()
@@ -42,14 +46,13 @@ func slurpFile(file *multipart.FileHeader) ([]byte, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func AttachmentUpload(ctxt ui.AmContext) (string, any, error) { func AttachmentUpload(ctxt ui.AmContext) (string, any) {
target := ctxt.FormField("tgt") target := ctxt.FormField("tgt")
postidStr := ctxt.FormField("post") postidStr := ctxt.FormField("post")
postId, err := strconv.ParseInt(postidStr, 10, 64) postId, err := strconv.ParseInt(postidStr, 10, 64)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, fmt.Errorf("internal error converting postID: %v", err)) return "error", fmt.Sprintf("internal error converting postID: %v", err)
} }
if ctxt.FormFieldIsSet("upload") { if ctxt.FormFieldIsSet("upload") {
file, err := ctxt.FormFile("thefile") file, err := ctxt.FormFile("thefile")
@@ -62,7 +65,7 @@ func AttachmentUpload(ctxt ui.AmContext) (string, any, error) {
if err == nil { if err == nil {
err = post.SetAttachment(ctxt.Ctx(), ctxt.CurrentUser(), file.Filename, file.Header.Get("Content-Type"), int32(file.Size), data, ctxt.RemoteIP()) err = post.SetAttachment(ctxt.Ctx(), ctxt.CurrentUser(), file.Filename, file.Header.Get("Content-Type"), int32(file.Size), data, ctxt.RemoteIP())
if err == nil { if err == nil {
return "redirect", target, nil return "redirect", target
} }
} }
} }
@@ -72,9 +75,9 @@ func AttachmentUpload(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("post", postId) ctxt.VarMap().Set("post", postId)
ctxt.VarMap().Set("amsterdam_pageTitle", "Upload Attachment") ctxt.VarMap().Set("amsterdam_pageTitle", "Upload Attachment")
ctxt.VarMap().Set("errorMessage", err.Error()) ctxt.VarMap().Set("errorMessage", err.Error())
return "framed_template", "attachment_upload.jet", nil return "framed", "attachment_upload.jet"
} }
return ui.ErrorPage(ctxt, errors.New("invalid button clicked on form")) return "error", "invalid button clicked on form"
} }
/* AttachmentSend sends the data of an attachment to the browser. /* AttachmentSend sends the data of an attachment to the browser.
@@ -83,30 +86,29 @@ func AttachmentUpload(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func AttachmentSend(ctxt ui.AmContext) (string, any, error) { func AttachmentSend(ctxt ui.AmContext) (string, any) {
postIdStr := ctxt.URLParam("post") postIdStr := ctxt.URLParam("post")
postId, err := strconv.ParseInt(postIdStr, 10, 64) postId, err := strconv.ParseInt(postIdStr, 10, 64)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, fmt.Errorf("internal error converting postID: %v", err)) return "error", fmt.Sprintf("internal error converting postID: %v", err)
} }
hdr, err := database.AmGetPost(ctxt.Ctx(), postId) hdr, err := database.AmGetPost(ctxt.Ctx(), postId)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
// Retrieve attachment info and data. // Retrieve attachment info and data.
info, err := hdr.AttachmentInfo(ctxt.Ctx()) info, err := hdr.AttachmentInfo(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} else if info == nil { } else if info == nil {
return ui.ErrorPage(ctxt, errors.New("attachment not found")) return "error", echo.NewHTTPError(http.StatusNotFound, "attachment not found")
} }
data, err := hdr.AttachmentData(ctxt.Ctx()) data, err := hdr.AttachmentData(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
// Record a "hit" on this attachment in the background. // Record a "hit" on this attachment in the background.
@@ -119,7 +121,7 @@ func AttachmentSend(ctxt ui.AmContext) (string, any, error) {
if !strings.HasPrefix(info.MIMEType, "image/") { if !strings.HasPrefix(info.MIMEType, "image/") {
ctxt.SetHeader("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", info.Filename)) ctxt.SetHeader("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", info.Filename))
} }
return "bytes", data, nil return "bytes", data
} }
/* ConfManage displays the "manage conference" page. /* ConfManage displays the "manage conference" page.
@@ -128,9 +130,8 @@ func AttachmentSend(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func ConfManage(ctxt ui.AmContext) (string, any, error) { func ConfManage(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
@@ -140,7 +141,7 @@ func ConfManage(ctxt ui.AmContext) (string, any, error) {
pseud, err := conf.DefaultPseud(ctxt.Ctx(), ctxt.CurrentUser()) pseud, err := conf.DefaultPseud(ctxt.Ctx(), ctxt.CurrentUser())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
ctxt.VarMap().Set("pseud", pseud) ctxt.VarMap().Set("pseud", pseud)
@@ -149,7 +150,7 @@ func ConfManage(ctxt ui.AmContext) (string, any, error) {
} else { } else {
member, _, _, err := comm.Membership(ctxt.Ctx(), ctxt.CurrentUser()) member, _, _, err := comm.Membership(ctxt.Ctx(), ctxt.CurrentUser())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
ctxt.VarMap().Set("canInvite", member) ctxt.VarMap().Set("canInvite", member)
} }
@@ -160,7 +161,7 @@ func ConfManage(ctxt ui.AmContext) (string, any, error) {
} }
ctxt.VarMap().Set("amsterdam_pageTitle", "Manage Conference: "+conf.Name) ctxt.VarMap().Set("amsterdam_pageTitle", "Manage Conference: "+conf.Name)
return "framed_template", "manage_conf.jet", nil return "framed", "manage_conf.jet"
} }
/* SetPseud sets the user's default pseud for the conference. /* SetPseud sets the user's default pseud for the conference.
@@ -169,17 +170,16 @@ func ConfManage(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func SetPseud(ctxt ui.AmContext) (string, any, error) { func SetPseud(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
pseud := ctxt.FormField("pseud") pseud := ctxt.FormField("pseud")
err := conf.SetDefaultPseud(ctxt.Ctx(), ctxt.CurrentUser(), pseud) err := conf.SetDefaultPseud(ctxt.Ctx(), ctxt.CurrentUser(), pseud)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias")), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias"))
} }
/* ConfFixseen marks all messages in a conference as read. /* ConfFixseen marks all messages in a conference as read.
@@ -188,16 +188,15 @@ func SetPseud(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func ConfFixseen(ctxt ui.AmContext) (string, any, error) { func ConfFixseen(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
err := conf.Fixseen(ctxt.Ctx(), ctxt.CurrentUser()) err := conf.Fixseen(ctxt.Ctx(), ctxt.CurrentUser())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias")), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias"))
} }
/* AddToHotlist adds the current community and conference to the user's hotlist.. /* AddToHotlist adds the current community and conference to the user's hotlist..
@@ -206,16 +205,15 @@ func ConfFixseen(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func AddToHotlist(ctxt ui.AmContext) (string, any, error) { func AddToHotlist(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
err := database.AmAppendToHotlist(ctxt.Ctx(), ctxt.CurrentUser(), comm.Id, conf.ConfId) err := database.AmAppendToHotlist(ctxt.Ctx(), ctxt.CurrentUser(), comm.Id, conf.ConfId)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, ctxt.GetScratch("currentAlias")), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, ctxt.GetScratch("currentAlias"))
} }
/* HideTopic hides or shows the current topic for the current user. /* HideTopic hides or shows the current topic for the current user.
@@ -224,19 +222,18 @@ func AddToHotlist(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func HideTopic(ctxt ui.AmContext) (string, any, error) { func HideTopic(ctxt ui.AmContext) (string, any) {
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
hidden, err := topic.IsHidden(ctxt.Ctx(), ctxt.CurrentUser()) hidden, err := topic.IsHidden(ctxt.Ctx(), ctxt.CurrentUser())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
err = topic.SetHidden(ctxt.Ctx(), ctxt.CurrentUser(), !hidden) err = topic.SetHidden(ctxt.Ctx(), ctxt.CurrentUser(), !hidden)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number)
} }
/* FreezeTopic freezes or unfreezes the current topic. /* FreezeTopic freezes or unfreezes the current topic.
@@ -245,21 +242,19 @@ func HideTopic(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func FreezeTopic(ctxt ui.AmContext) (string, any, error) { func FreezeTopic(ctxt ui.AmContext) (string, any) {
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
if !conf.TestPermission("Conference.Hide", myLevel) { if !conf.TestPermission("Conference.Hide", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
err := topic.SetFrozen(ctxt.Ctx(), !topic.Frozen, ctxt.CurrentUser(), ctxt.RemoteIP()) err := topic.SetFrozen(ctxt.Ctx(), !topic.Frozen, ctxt.CurrentUser(), ctxt.RemoteIP())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number)
} }
/* ArchiveTopic archives or unarchives the current topic. /* ArchiveTopic archives or unarchives the current topic.
@@ -268,21 +263,19 @@ func FreezeTopic(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func ArchiveTopic(ctxt ui.AmContext) (string, any, error) { func ArchiveTopic(ctxt ui.AmContext) (string, any) {
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
if !conf.TestPermission("Conference.Hide", myLevel) { if !conf.TestPermission("Conference.Hide", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
err := topic.SetArchived(ctxt.Ctx(), !topic.Archived, ctxt.CurrentUser(), ctxt.RemoteIP()) err := topic.SetArchived(ctxt.Ctx(), !topic.Archived, ctxt.CurrentUser(), ctxt.RemoteIP())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number)
} }
/* StickTopic sticks or unsticks the current topic. /* StickTopic sticks or unsticks the current topic.
@@ -291,21 +284,19 @@ func ArchiveTopic(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func StickTopic(ctxt ui.AmContext) (string, any, error) { func StickTopic(ctxt ui.AmContext) (string, any) {
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
if !conf.TestPermission("Conference.Hide", myLevel) { if !conf.TestPermission("Conference.Hide", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
err := topic.SetSticky(ctxt.Ctx(), !topic.Sticky, ctxt.CurrentUser(), ctxt.RemoteIP()) err := topic.SetSticky(ctxt.Ctx(), !topic.Sticky, ctxt.CurrentUser(), ctxt.RemoteIP())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number)
} }
/* DeleteTopic deletes the current topic. /* DeleteTopic deletes the current topic.
@@ -314,32 +305,29 @@ func StickTopic(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func DeleteTopic(ctxt ui.AmContext) (string, any, error) { func DeleteTopic(ctxt ui.AmContext) (string, any) {
if ctxt.CurrentUser().IsAnon { if ctxt.CurrentUser().IsAnon {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
if !conf.TestPermission("Conference.Nuke", myLevel) { if !conf.TestPermission("Conference.Nuke", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
// Load the message box, and, if we have a valid "yes," then perform the delete // Load the message box, and, if we have a valid "yes," then perform the delete
mbox, err := ui.AmLoadMessageBox("deleteTopic") mbox, err := ui.AmLoadMessageBox("deleteTopic")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
if mbox.Validate(ctxt, "yes") { if mbox.Validate(ctxt, "yes") {
err := topic.Delete(ctxt.Ctx(), ctxt.CurrentUser(), ctxt.RemoteIP(), ampool) err := topic.Delete(ctxt.Ctx(), ctxt.CurrentUser(), ctxt.RemoteIP(), ampool)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias")), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"))
} }
// Set up to display the message box. // Set up to display the message box.
@@ -356,35 +344,32 @@ func DeleteTopic(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func HideMessage(ctxt ui.AmContext) (string, any, error) { func HideMessage(ctxt ui.AmContext) (string, any) {
if ctxt.CurrentUser().IsAnon { if ctxt.CurrentUser().IsAnon {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
msgNum, err := strconv.Atoi(ctxt.URLParam("msg")) msgNum, err := strconv.Atoi(ctxt.URLParam("msg"))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
hdrs, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(msgNum), int32(msgNum)) hdrs, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(msgNum), int32(msgNum))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} else if len(hdrs) != 1 { } else if len(hdrs) != 1 {
return ui.ErrorPage(ctxt, errors.New("internal error getting post reference")) return "error", EPOSTREF
} }
if (hdrs[0].CreatorUid != ctxt.CurrentUserId()) && !conf.TestPermission("Conference.Hide", myLevel) { if (hdrs[0].CreatorUid != ctxt.CurrentUserId()) && !conf.TestPermission("Conference.Hide", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
err = hdrs[0].SetHidden(ctxt.Ctx(), ctxt.CurrentUser(), !(hdrs[0].Hidden), ctxt.RemoteIP()) err = hdrs[0].SetHidden(ctxt.Ctx(), ctxt.CurrentUser(), !(hdrs[0].Hidden), ctxt.RemoteIP())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d?r=%d&ac=1", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number, hdrs[0].Num), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d?r=%d&ac=1", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number, hdrs[0].Num)
} }
/* ScribbleMessage scribbles a topic message. /* ScribbleMessage scribbles a topic message.
@@ -393,35 +378,32 @@ func HideMessage(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func ScribbleMessage(ctxt ui.AmContext) (string, any, error) { func ScribbleMessage(ctxt ui.AmContext) (string, any) {
if ctxt.CurrentUser().IsAnon { if ctxt.CurrentUser().IsAnon {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
msgNum, err := strconv.Atoi(ctxt.URLParam("msg")) msgNum, err := strconv.Atoi(ctxt.URLParam("msg"))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
hdrs, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(msgNum), int32(msgNum)) hdrs, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(msgNum), int32(msgNum))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} else if len(hdrs) != 1 { } else if len(hdrs) != 1 {
return ui.ErrorPage(ctxt, errors.New("internal error getting post reference")) return "error", EPOSTREF
} }
if (hdrs[0].CreatorUid != ctxt.CurrentUserId()) && !conf.TestPermission("Conference.Nuke", myLevel) { if (hdrs[0].CreatorUid != ctxt.CurrentUserId()) && !conf.TestPermission("Conference.Nuke", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
err = hdrs[0].Scribble(ctxt.Ctx(), ctxt.CurrentUser(), ctxt.RemoteIP()) err = hdrs[0].Scribble(ctxt.Ctx(), ctxt.CurrentUser(), ctxt.RemoteIP())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d?r=%d&ac=1", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number, hdrs[0].Num), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d?r=%d&ac=1", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number, hdrs[0].Num)
} }
/* NukeMessage nukes (deletes entirely) a topic message. /* NukeMessage nukes (deletes entirely) a topic message.
@@ -430,53 +412,50 @@ func ScribbleMessage(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func NukeMessage(ctxt ui.AmContext) (string, any, error) { func NukeMessage(ctxt ui.AmContext) (string, any) {
if ctxt.CurrentUser().IsAnon { if ctxt.CurrentUser().IsAnon {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
msgNum, err := strconv.Atoi(ctxt.URLParam("msg")) msgNum, err := strconv.Atoi(ctxt.URLParam("msg"))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
hdrs, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(msgNum), int32(msgNum)) hdrs, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(msgNum), int32(msgNum))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} else if len(hdrs) != 1 { } else if len(hdrs) != 1 {
return ui.ErrorPage(ctxt, errors.New("internal error getting post reference")) return "error", EPOSTREF
} }
if !conf.TestPermission("Conference.Nuke", myLevel) { if !conf.TestPermission("Conference.Nuke", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
// Load the message box, and, if we have a valid "yes," then perform the nuke! // Load the message box, and, if we have a valid "yes," then perform the nuke!
mbox, err := ui.AmLoadMessageBox("nuke") mbox, err := ui.AmLoadMessageBox("nuke")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
if mbox.Validate(ctxt, "yes") { if mbox.Validate(ctxt, "yes") {
// do the nuking! // do the nuking!
err := hdrs[0].Nuke(ctxt.Ctx(), ctxt.CurrentUser(), ctxt.RemoteIP()) err := hdrs[0].Nuke(ctxt.Ctx(), ctxt.CurrentUser(), ctxt.RemoteIP())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number)
} }
// Set up to display the message box. // Set up to display the message box.
link, err := hdrs[0].Link(ctxt.Ctx(), "community") link, err := hdrs[0].Link(ctxt.Ctx(), "community")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
creator, err := hdrs[0].Creator(ctxt.Ctx()) creator, err := hdrs[0].Creator(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
mbox.SetMessage(fmt.Sprintf(`You are about to nuke message <span class="font-mono font-bold text-red-600">&lt;%s&gt;</span>, mbox.SetMessage(fmt.Sprintf(`You are about to nuke message <span class="font-mono font-bold text-red-600">&lt;%s&gt;</span>,
originally composed by <span class="font-bold text-red-600">&lt;%s&gt;</span>!`, link, creator.Username)) originally composed by <span class="font-bold text-red-600">&lt;%s&gt;</span>!`, link, creator.Username))
@@ -491,40 +470,37 @@ func NukeMessage(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func MoveMessageForm(ctxt ui.AmContext) (string, any, error) { func MoveMessageForm(ctxt ui.AmContext) (string, any) {
if ctxt.CurrentUser().IsAnon { if ctxt.CurrentUser().IsAnon {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
msgNum, err := strconv.Atoi(ctxt.URLParam("msg")) msgNum, err := strconv.Atoi(ctxt.URLParam("msg"))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
hdrs, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(msgNum), int32(msgNum)) hdrs, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(msgNum), int32(msgNum))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} else if len(hdrs) != 1 { } else if len(hdrs) != 1 {
return ui.ErrorPage(ctxt, errors.New("internal error getting post reference")) return "error", EPOSTREF
} }
if !conf.TestPermission("Conference.Nuke", myLevel) || !conf.TestPermission("Conference.Post", myLevel) || topic.TopMessage == 0 { if !conf.TestPermission("Conference.Nuke", myLevel) || !conf.TestPermission("Conference.Post", myLevel) || topic.TopMessage == 0 {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
creator, err := hdrs[0].Creator(ctxt.Ctx()) creator, err := hdrs[0].Creator(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
ctxt.VarMap().Set("creator", creator) ctxt.VarMap().Set("creator", creator)
topiclist, err := database.AmListTopics(ctxt.Ctx(), conf.ConfId, ctxt.CurrentUserId(), database.TopicViewAll, database.TopicSortName, true) topiclist, err := database.AmListTopics(ctxt.Ctx(), conf.ConfId, ctxt.CurrentUserId(), database.TopicViewAll, database.TopicSortName, true)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
for i := range topiclist { for i := range topiclist {
if topiclist[i].TopicID == topic.TopicId { if topiclist[i].TopicID == topic.TopicId {
@@ -540,7 +516,7 @@ func MoveMessageForm(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("formLink", formLink) ctxt.VarMap().Set("formLink", formLink)
ctxt.VarMap().Set("amsterdam_pageTitle", "Move Message") ctxt.VarMap().Set("amsterdam_pageTitle", "Move Message")
return "framed_template", "move_message.jet", nil return "framed", "move_message.jet"
} }
/* PublishMessage publishes a message to the front page. /* PublishMessage publishes a message to the front page.
@@ -549,30 +525,28 @@ func MoveMessageForm(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func PublishMessage(ctxt ui.AmContext) (string, any, error) { func PublishMessage(ctxt ui.AmContext) (string, any) {
if !ctxt.TestPermission("Global.PublishFP") { if !ctxt.TestPermission("Global.PublishFP") {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
msgNum, err := strconv.Atoi(ctxt.URLParam("msg")) msgNum, err := strconv.Atoi(ctxt.URLParam("msg"))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
hdrs, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(msgNum), int32(msgNum)) hdrs, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(msgNum), int32(msgNum))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} else if len(hdrs) != 1 { } else if len(hdrs) != 1 {
return ui.ErrorPage(ctxt, errors.New("internal error getting post reference")) return "error", EPOSTREF
} }
if err = hdrs[0].Publish(ctxt.Ctx(), comm, ctxt.CurrentUser(), ctxt.RemoteIP()); err != nil { if err = hdrs[0].Publish(ctxt.Ctx(), comm, ctxt.CurrentUser(), ctxt.RemoteIP()); err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d?r=%d&ac=1", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number, hdrs[0].Num), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d?r=%d&ac=1", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number, hdrs[0].Num)
} }
/* MoveMessage moves a message to a different topic. /* MoveMessage moves a message to a different topic.
@@ -581,12 +555,10 @@ func PublishMessage(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func MoveMessage(ctxt ui.AmContext) (string, any, error) { func MoveMessage(ctxt ui.AmContext) (string, any) {
if ctxt.CurrentUser().IsAnon { if ctxt.CurrentUser().IsAnon {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
@@ -594,34 +566,33 @@ func MoveMessage(ctxt ui.AmContext) (string, any, error) {
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
msgNum, err := strconv.Atoi(ctxt.URLParam("msg")) msgNum, err := strconv.Atoi(ctxt.URLParam("msg"))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
hdrs, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(msgNum), int32(msgNum)) hdrs, err := database.AmGetPostRange(ctxt.Ctx(), topic, int32(msgNum), int32(msgNum))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} else if len(hdrs) != 1 { } else if len(hdrs) != 1 {
return ui.ErrorPage(ctxt, errors.New("internal error getting post reference")) return "error", EPOSTREF
} }
if ctxt.FormFieldIsSet("cancel") { if ctxt.FormFieldIsSet("cancel") {
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d?r=%d&ac=1", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number, hdrs[0].Num), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d?r=%d&ac=1", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number, hdrs[0].Num)
} }
if !conf.TestPermission("Conference.Nuke", myLevel) || !conf.TestPermission("Conference.Post", myLevel) || topic.TopMessage == 0 { if !conf.TestPermission("Conference.Nuke", myLevel) || !conf.TestPermission("Conference.Post", myLevel) || topic.TopMessage == 0 {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
targetId, err := ctxt.FormFieldInt("target") targetId, err := ctxt.FormFieldInt("target")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
target, err := database.AmGetTopic(ctxt.Ctx(), int32(targetId)) target, err := database.AmGetTopic(ctxt.Ctx(), int32(targetId))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
// Move the topic! // Move the topic!
err = hdrs[0].MoveTo(ctxt.Ctx(), target, ctxt.CurrentUser(), ctxt.RemoteIP()) err = hdrs[0].MoveTo(ctxt.Ctx(), target, ctxt.CurrentUser(), ctxt.RemoteIP())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
// Now, we need to send this post to whoever subscribed to the NEW topic. But it's tricky because we don't have // Now, we need to send this post to whoever subscribed to the NEW topic. But it's tricky because we don't have
@@ -646,7 +617,7 @@ func MoveMessage(ctxt ui.AmContext) (string, any, error) {
}) })
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/r/%d", ctxt.CurrentCommunity().Alias, ctxt.GetScratch("currentAlias"), topic.Number)
} }
/* TopicManage displays the "manage topic" page. /* TopicManage displays the "manage topic" page.
@@ -655,9 +626,8 @@ func MoveMessage(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func TopicManage(ctxt ui.AmContext) (string, any, error) { func TopicManage(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
ctxt.VarMap().Set("backlink", fmt.Sprintf("/comm/%s/conf/%s/r/%d", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number)) ctxt.VarMap().Set("backlink", fmt.Sprintf("/comm/%s/conf/%s/r/%d", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number))
@@ -668,26 +638,26 @@ func TopicManage(ctxt ui.AmContext) (string, any, error) {
// Get the invitation flag. // Get the invitation flag.
member, _, _, err := comm.Membership(ctxt.Ctx(), ctxt.CurrentUser()) member, _, _, err := comm.Membership(ctxt.Ctx(), ctxt.CurrentUser())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
ctxt.VarMap().Set("canInvite", member) ctxt.VarMap().Set("canInvite", member)
// Get the E-mail subscription status. // Get the E-mail subscription status.
sub, err := topic.IsSubscribed(ctxt.Ctx(), ctxt.CurrentUser()) sub, err := topic.IsSubscribed(ctxt.Ctx(), ctxt.CurrentUser())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
ctxt.VarMap().Set("subscribed", sub) ctxt.VarMap().Set("subscribed", sub)
// Get the filtered users list. // Get the filtered users list.
bozos, err := topic.GetBozos(ctxt.Ctx(), ctxt.CurrentUser()) bozos, err := topic.GetBozos(ctxt.Ctx(), ctxt.CurrentUser())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
ctxt.VarMap().Set("bozos", bozos) ctxt.VarMap().Set("bozos", bozos)
ctxt.VarMap().Set("amsterdam_pageTitle", "Manage Topic: "+topic.Name) ctxt.VarMap().Set("amsterdam_pageTitle", "Manage Topic: "+topic.Name)
return "framed_template", "manage_topic.jet", nil return "framed", "manage_topic.jet"
} }
/* TopicSetSubscribe toggles the "subscription" flag on the current topic for the current user. /* TopicSetSubscribe toggles the "subscription" flag on the current topic for the current user.
@@ -696,24 +666,22 @@ func TopicManage(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func TopicSetSubscribe(ctxt ui.AmContext) (string, any, error) { func TopicSetSubscribe(ctxt ui.AmContext) (string, any) {
if ctxt.CurrentUser().IsAnon { if ctxt.CurrentUser().IsAnon {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
flag, err := topic.IsSubscribed(ctxt.Ctx(), ctxt.CurrentUser()) flag, err := topic.IsSubscribed(ctxt.Ctx(), ctxt.CurrentUser())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
err = topic.SetSubscribed(ctxt.Ctx(), ctxt.CurrentUser(), !flag) err = topic.SetSubscribed(ctxt.Ctx(), ctxt.CurrentUser(), !flag)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/op/%d/manage", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/op/%d/manage", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number)
} }
/* TopicRemoveBozo removes filtering from a specified user in the topic. /* TopicRemoveBozo removes filtering from a specified user in the topic.
@@ -722,18 +690,17 @@ func TopicSetSubscribe(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func TopicRemoveBozo(ctxt ui.AmContext) (string, any, error) { func TopicRemoveBozo(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
bozoUid, err := strconv.Atoi(ctxt.URLParam("uid")) bozoUid, err := strconv.Atoi(ctxt.URLParam("uid"))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
err = topic.SetBozo(ctxt.Ctx(), ctxt.CurrentUser(), int32(bozoUid), false) err = topic.SetBozo(ctxt.Ctx(), ctxt.CurrentUser(), int32(bozoUid), false)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/op/%d/manage", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/op/%d/manage", comm.Alias, ctxt.GetScratch("currentAlias"), topic.Number)
} }
+32 -47
View File
@@ -13,7 +13,6 @@ package main
import ( import (
"errors" "errors"
"fmt" "fmt"
"net/http"
"strconv" "strconv"
"strings" "strings"
@@ -29,20 +28,18 @@ import (
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func EditConferenceForm(ctxt ui.AmContext) (string, any, error) { func EditConferenceForm(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
if !conf.TestPermission("Conference.Change", myLevel) { if !conf.TestPermission("Conference.Change", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
dlg, err := ui.AmLoadDialog("edit_conference") dlg, err := ui.AmLoadDialog("edit_conference")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
dlg.SetCommunity(comm) dlg.SetCommunity(comm)
dlg.SetConference(conf, ctxt.GetScratch("currentAlias").(string)) dlg.SetConference(conf, ctxt.GetScratch("currentAlias").(string))
@@ -51,7 +48,7 @@ func EditConferenceForm(ctxt ui.AmContext) (string, any, error) {
if comm.TestPermission("Community.Create", ctxt.EffectiveLevel()) { if comm.TestPermission("Community.Create", ctxt.EffectiveLevel()) {
f, err := conf.HiddenInList(ctxt.Ctx(), comm) f, err := conf.HiddenInList(ctxt.Ctx(), comm)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
dlg.Field("hide").SetChecked(f) dlg.Field("hide").SetChecked(f)
} else { } else {
@@ -66,7 +63,7 @@ func EditConferenceForm(ctxt ui.AmContext) (string, any, error) {
dlg.Field("delete_lvl").SetLevel(conf.DeleteLevel) dlg.Field("delete_lvl").SetLevel(conf.DeleteLevel)
flags, err := conf.Flags(ctxt.Ctx()) flags, err := conf.Flags(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
dlg.Field("pic_in_post").SetChecked(flags.Get(database.ConferenceFlagPicturesInPosts)) dlg.Field("pic_in_post").SetChecked(flags.Get(database.ConferenceFlagPicturesInPosts))
return dlg.Render(ctxt) return dlg.Render(ctxt)
@@ -78,24 +75,22 @@ func EditConferenceForm(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func EditConference(ctxt ui.AmContext) (string, any, error) { func EditConference(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
if !conf.TestPermission("Conference.Change", myLevel) { if !conf.TestPermission("Conference.Change", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
dlg, err := ui.AmLoadDialog("edit_conference") dlg, err := ui.AmLoadDialog("edit_conference")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
button := dlg.WhichButton(ctxt) button := dlg.WhichButton(ctxt)
if button == "cancel" { if button == "cancel" {
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias")), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias"))
} else if button != "update" { } else if button != "update" {
dlg.SetCommunity(comm) dlg.SetCommunity(comm)
dlg.SetConference(conf, ctxt.GetScratch("currentAlias").(string)) dlg.SetConference(conf, ctxt.GetScratch("currentAlias").(string))
@@ -123,7 +118,7 @@ func EditConference(ctxt ui.AmContext) (string, any, error) {
return dlg.RenderError(ctxt, err.Error()) return dlg.RenderError(ctxt, err.Error())
} }
return "redirect", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias")), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias"))
} }
/* ConferenceAliasForm displays the form for managing conference aliases. /* ConferenceAliasForm displays the form for managing conference aliases.
@@ -132,15 +127,13 @@ func EditConference(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func ConferenceAliasForm(ctxt ui.AmContext) (string, any, error) { func ConferenceAliasForm(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
if !conf.TestPermission("Conference.Change", myLevel) { if !conf.TestPermission("Conference.Change", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
ctxt.VarMap().Set("newAlias", "") ctxt.VarMap().Set("newAlias", "")
@@ -158,11 +151,11 @@ func ConferenceAliasForm(ctxt ui.AmContext) (string, any, error) {
aliases, err := conf.Aliases(ctxt.Ctx()) aliases, err := conf.Aliases(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
ctxt.VarMap().Set("aliases", aliases) ctxt.VarMap().Set("aliases", aliases)
return "framed_template", "conf_aliases.jet", nil return "framed", "conf_aliases.jet"
} }
/* ConferenceAliasAdd adds a new alias to the current conference. /* ConferenceAliasAdd adds a new alias to the current conference.
@@ -171,15 +164,13 @@ func ConferenceAliasForm(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func ConferenceAliasAdd(ctxt ui.AmContext) (string, any, error) { func ConferenceAliasAdd(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
if !conf.TestPermission("Conference.Change", myLevel) { if !conf.TestPermission("Conference.Change", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
ctxt.VarMap().Set("confName", conf.Name) ctxt.VarMap().Set("confName", conf.Name)
@@ -207,12 +198,12 @@ func ConferenceAliasAdd(ctxt ui.AmContext) (string, any, error) {
aliases, err := conf.Aliases(ctxt.Ctx()) aliases, err := conf.Aliases(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
ctxt.VarMap().Set("newAlias", "") ctxt.VarMap().Set("newAlias", "")
ctxt.VarMap().Set("aliases", aliases) ctxt.VarMap().Set("aliases", aliases)
return "framed_template", "conf_aliases.jet", nil return "framed", "conf_aliases.jet"
} }
// CMData is the result data passed to the conference members page. // CMData is the result data passed to the conference members page.
@@ -242,15 +233,13 @@ var operMap = map[string]int{
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func ConferenceMembers(ctxt ui.AmContext) (string, any, error) { func ConferenceMembers(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16) myLevel := ctxt.GetScratch("levelInConference").(uint16)
if !conf.TestPermission("Conference.Change", myLevel) { if !conf.TestPermission("Conference.Change", myLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
// Set the first batch of page variables. // Set the first batch of page variables.
@@ -324,7 +313,7 @@ func ConferenceMembers(ctxt ui.AmContext) (string, any, error) {
} }
} }
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
} }
} }
@@ -334,7 +323,7 @@ func ConferenceMembers(ctxt ui.AmContext) (string, any, error) {
// Get the member list for the conference. // Get the member list for the conference.
members, err := conf.Members(ctxt.Ctx()) members, err := conf.Members(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
// Generate the result list. // Generate the result list.
@@ -357,7 +346,7 @@ func ConferenceMembers(ctxt ui.AmContext) (string, any, error) {
case "comm": case "comm":
ulist, t, err := database.AmSearchCommunityMembers(ctxt.Ctx(), comm, fieldMap[field], operMap[oper], term, offset, int(maxPage)) ulist, t, err := database.AmSearchCommunityMembers(ctxt.Ctx(), comm, fieldMap[field], operMap[oper], term, offset, int(maxPage))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
total = t total = t
mr = make([]CMData, len(ulist)) mr = make([]CMData, len(ulist))
@@ -385,7 +374,7 @@ func ConferenceMembers(ctxt ui.AmContext) (string, any, error) {
if (offset + len(mr)) < total { if (offset + len(mr)) < total {
ctxt.VarMap().Set("showNext", true) ctxt.VarMap().Set("showNext", true)
} }
return "framed_template", "conf_members.jet", nil return "framed", "conf_members.jet"
} }
/* CreateConferenceForm displays the dialog for creating a new conference. /* CreateConferenceForm displays the dialog for creating a new conference.
@@ -394,18 +383,16 @@ func ConferenceMembers(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func CreateConferenceForm(ctxt ui.AmContext) (string, any, error) { func CreateConferenceForm(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
if !comm.TestPermission("Community.Create", ctxt.EffectiveLevel()) { if !comm.TestPermission("Community.Create", ctxt.EffectiveLevel()) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
dlg, err := ui.AmLoadDialog("create_conference") dlg, err := ui.AmLoadDialog("create_conference")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
dlg.SetCommunity(comm) dlg.SetCommunity(comm)
return dlg.Render(ctxt) return dlg.Render(ctxt)
@@ -417,22 +404,20 @@ func CreateConferenceForm(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func CreateConference(ctxt ui.AmContext) (string, any, error) { func CreateConference(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
if !comm.TestPermission("Community.Create", ctxt.EffectiveLevel()) { if !comm.TestPermission("Community.Create", ctxt.EffectiveLevel()) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
dlg, err := ui.AmLoadDialog("create_conference") dlg, err := ui.AmLoadDialog("create_conference")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
button := dlg.WhichButton(ctxt) button := dlg.WhichButton(ctxt)
if button == "cancel" { if button == "cancel" {
return "redirect", fmt.Sprintf("/comm/%s/conf", comm.Alias), nil return "redirect", fmt.Sprintf("/comm/%s/conf", comm.Alias)
} else if button != "create" { } else if button != "create" {
dlg.SetCommunity(comm) dlg.SetCommunity(comm)
return dlg.RenderError(ctxt, "invalid button pressed") return dlg.RenderError(ctxt, "invalid button pressed")
@@ -446,5 +431,5 @@ func CreateConference(ctxt ui.AmContext) (string, any, error) {
return dlg.RenderError(ctxt, err.Error()) return dlg.RenderError(ctxt, err.Error())
} }
log.Infof("Created conference '%s'", conf.Name) log.Infof("Created conference '%s'", conf.Name)
return "redirect", fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, alias), nil return "redirect", fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, alias)
} }
+6 -4
View File
@@ -10,7 +10,6 @@
package main package main
import ( import (
"errors"
"net/http" "net/http"
"git.erbosoft.com/amy/amsterdam/ui" "git.erbosoft.com/amy/amsterdam/ui"
@@ -19,7 +18,10 @@ import (
) )
// ENOPERM is the standard "not permitted" error message. // ENOPERM is the standard "not permitted" error message.
var ENOPERM error = errors.New("you are not permitted to perform this operation") var ENOPERM *echo.HTTPError = echo.NewHTTPError(http.StatusForbidden, "you are not permitted to perform this operation")
// ENOACCESS is the standard "no access" error message.
var ENOACCESS *echo.HTTPError = echo.NewHTTPError(http.StatusForbidden, "you are not permitted to access this page")
/* NotImplPage is used for all TODO links, to show that something hasn't yet been implemented. /* NotImplPage is used for all TODO links, to show that something hasn't yet been implemented.
* Parameters: * Parameters:
@@ -29,11 +31,11 @@ var ENOPERM error = errors.New("you are not permitted to perform this operation"
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status. * Standard Go error status.
*/ */
func NotImplPage(ctxt ui.AmContext) (string, any, error) { func NotImplPage(ctxt ui.AmContext) (string, any) {
ctxt.SetLeftMenu("top") ctxt.SetLeftMenu("top")
ctxt.VarMap().Set("amsterdam_pageTitle", "Function Not Implemented") ctxt.VarMap().Set("amsterdam_pageTitle", "Function Not Implemented")
ctxt.VarMap().Set("path", ctxt.URLPath()) ctxt.VarMap().Set("path", ctxt.URLPath())
return "framed_template", "notimpl.jet", nil return "framed", "notimpl.jet"
} }
/* AmErrorHandler handles all the mundane HTTP errors generated by the Echo engine. /* AmErrorHandler handles all the mundane HTTP errors generated by the Echo engine.
+22 -30
View File
@@ -91,9 +91,8 @@ func loadCategoryInformation(ctxt ui.AmContext, offset int) error {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func FindPage(ctxt ui.AmContext) (string, any, error) { func FindPage(ctxt ui.AmContext) (string, any) {
mode := "" mode := ""
p := ctxt.Parameter("mode") p := ctxt.Parameter("mode")
if p != "" { if p != "" {
@@ -128,7 +127,7 @@ func FindPage(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("term", "") ctxt.VarMap().Set("term", "")
err := loadCategoryInformation(ctxt, ofs) err := loadCategoryInformation(ctxt, ofs)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
case "USR": case "USR":
ctxt.VarMap().Set("field", "name") ctxt.VarMap().Set("field", "name")
@@ -146,7 +145,7 @@ func FindPage(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("amsterdam_pageTitle", "Find") ctxt.VarMap().Set("amsterdam_pageTitle", "Find")
ctxt.SetLeftMenu("top") ctxt.SetLeftMenu("top")
return "framed_template", "find.jet", nil return "framed", "find.jet"
} }
/* Find performs the "find" operation. /* Find performs the "find" operation.
@@ -155,9 +154,8 @@ func FindPage(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func Find(ctxt ui.AmContext) (string, any, error) { func Find(ctxt ui.AmContext) (string, any) {
if !ctxt.GlobalFlags().Get(database.GlobalFlagNoCategories) { if !ctxt.GlobalFlags().Get(database.GlobalFlagNoCategories) {
ctxt.VarMap().Set("catIsPresent", true) ctxt.VarMap().Set("catIsPresent", true)
} }
@@ -193,7 +191,7 @@ func Find(ctxt ui.AmContext) (string, any, error) {
iField = database.SearchCommFieldSynopsis iField = database.SearchCommFieldSynopsis
default: default:
ctxt.VarMap().Set("errorMessage", "invalid parameter to find") ctxt.VarMap().Set("errorMessage", "invalid parameter to find")
return "framed_template", "find.jet", nil return "framed", "find.jet"
} }
switch oper { switch oper {
case "st": case "st":
@@ -204,7 +202,7 @@ func Find(ctxt ui.AmContext) (string, any, error) {
iOper = database.SearchCommOperRegex iOper = database.SearchCommOperRegex
default: default:
ctxt.VarMap().Set("errorMessage", "invalid parameter to find") ctxt.VarMap().Set("errorMessage", "invalid parameter to find")
return "framed_template", "find.jet", nil return "framed", "find.jet"
} }
var clist []*database.Community var clist []*database.Community
clist, total, err = database.AmSearchCommunities(ctxt.Ctx(), iField, iOper, term, ofs*listMax, listMax, clist, total, err = database.AmSearchCommunities(ctxt.Ctx(), iField, iOper, term, ofs*listMax, listMax,
@@ -230,7 +228,7 @@ func Find(ctxt ui.AmContext) (string, any, error) {
iField = database.SearchUserFieldLastName iField = database.SearchUserFieldLastName
default: default:
ctxt.VarMap().Set("errorMessage", "invalid parameter to find") ctxt.VarMap().Set("errorMessage", "invalid parameter to find")
return "framed_template", "find.jet", nil return "framed", "find.jet"
} }
switch oper { switch oper {
case "st": case "st":
@@ -241,7 +239,7 @@ func Find(ctxt ui.AmContext) (string, any, error) {
iOper = database.SearchUserOperRegex iOper = database.SearchUserOperRegex
default: default:
ctxt.VarMap().Set("errorMessage", "invalid parameter to find") ctxt.VarMap().Set("errorMessage", "invalid parameter to find")
return "framed_template", "find.jet", nil return "framed", "find.jet"
} }
var ulist []*database.User var ulist []*database.User
ulist, total, err = database.AmSearchUsers(ctxt.Ctx(), iField, iOper, term, ofs*listMax, listMax) ulist, total, err = database.AmSearchUsers(ctxt.Ctx(), iField, iOper, term, ofs*listMax, listMax)
@@ -265,7 +263,7 @@ func Find(ctxt ui.AmContext) (string, any, error) {
iOper = database.SearchCatOperRegex iOper = database.SearchCatOperRegex
default: default:
ctxt.VarMap().Set("errorMessage", "invalid parameter to find") ctxt.VarMap().Set("errorMessage", "invalid parameter to find")
return "framed_template", "find.jet", nil return "framed", "find.jet"
} }
var catlist []*database.Category var catlist []*database.Category
catlist, total, err = database.AmSearchCategories(ctxt.Ctx(), iOper, term, ofs*listMax, listMax, catlist, total, err = database.AmSearchCategories(ctxt.Ctx(), iOper, term, ofs*listMax, listMax,
@@ -288,7 +286,7 @@ func Find(ctxt ui.AmContext) (string, any, error) {
} }
if err != nil { if err != nil {
ctxt.VarMap().Set("errorMessage", err.Error()) ctxt.VarMap().Set("errorMessage", err.Error())
return "framed_template", "find.jet", nil return "framed", "find.jet"
} }
if numResults == 0 { if numResults == 0 {
ctxt.VarMap().Set("resultHeader", "Search Results: (None)") ctxt.VarMap().Set("resultHeader", "Search Results: (None)")
@@ -302,11 +300,11 @@ func Find(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("resultShowNext", true) ctxt.VarMap().Set("resultShowNext", true)
} }
} }
return "framed_template", "find.jet", nil return "framed", "find.jet"
} }
// commonFindGetBackend is the common "back end" function for Find Posts in Community/Conference/Topic. // commonFindGetBackend is the common "back end" function for Find Posts in Community/Conference/Topic.
func commonFindGetBackend(ctxt ui.AmContext) (string, any, error) { func commonFindGetBackend(ctxt ui.AmContext) (string, any) {
ofs := 0 ofs := 0
p := ctxt.Parameter("ofs") p := ctxt.Parameter("ofs")
if p != "" { if p != "" {
@@ -318,7 +316,7 @@ func commonFindGetBackend(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("ofs", ofs) ctxt.VarMap().Set("ofs", ofs)
ctxt.VarMap().Set("term", "") ctxt.VarMap().Set("term", "")
ctxt.VarMap().Set("amsterdam_pageTitle", "Find Posts") ctxt.VarMap().Set("amsterdam_pageTitle", "Find Posts")
return "framed_template", "find_posts.jet", nil return "framed", "find_posts.jet"
} }
/* FindPostsPageCommunity renders the page for finding posts in a community. /* FindPostsPageCommunity renders the page for finding posts in a community.
@@ -327,9 +325,8 @@ func commonFindGetBackend(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func FindPostsPageCommunity(ctxt ui.AmContext) (string, any, error) { func FindPostsPageCommunity(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
ctxt.VarMap().Set("scope", "community") ctxt.VarMap().Set("scope", "community")
ctxt.VarMap().Set("entityName", comm.Name) ctxt.VarMap().Set("entityName", comm.Name)
@@ -344,9 +341,8 @@ func FindPostsPageCommunity(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func FindPostsPageConference(ctxt ui.AmContext) (string, any, error) { func FindPostsPageConference(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
ctxt.VarMap().Set("scope", "conference") ctxt.VarMap().Set("scope", "conference")
@@ -362,9 +358,8 @@ func FindPostsPageConference(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func FindPostsPageTopic(ctxt ui.AmContext) (string, any, error) { func FindPostsPageTopic(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
ctxt.VarMap().Set("scope", "topic") ctxt.VarMap().Set("scope", "topic")
@@ -375,7 +370,7 @@ func FindPostsPageTopic(ctxt ui.AmContext) (string, any, error) {
} }
// commonFindPostBackend is the common "back end" function for Find Posts in Community/Conference/Topic. // commonFindPostBackend is the common "back end" function for Find Posts in Community/Conference/Topic.
func commonFindPostBackend(ctxt ui.AmContext, comm *database.Community, conf *database.Conference, topic *database.Topic) (string, any, error) { func commonFindPostBackend(ctxt ui.AmContext, comm *database.Community, conf *database.Conference, topic *database.Topic) (string, any) {
term := ctxt.FormField("term") term := ctxt.FormField("term")
ctxt.VarMap().Set("term", term) ctxt.VarMap().Set("term", term)
ctxt.VarMap().Set("amsterdam_pageTitle", "Find Posts") ctxt.VarMap().Set("amsterdam_pageTitle", "Find Posts")
@@ -396,7 +391,7 @@ func commonFindPostBackend(ctxt ui.AmContext, comm *database.Community, conf *da
ctxt.VarMap().Set("resultList", postlist) ctxt.VarMap().Set("resultList", postlist)
} else { } else {
ctxt.VarMap().Set("errorMessage", err.Error()) ctxt.VarMap().Set("errorMessage", err.Error())
return "framed_template", "find_posts.jet", nil return "framed", "find_posts.jet"
} }
if numResults == 0 { if numResults == 0 {
ctxt.VarMap().Set("resultHeader", "Search Results: (None)") ctxt.VarMap().Set("resultHeader", "Search Results: (None)")
@@ -410,7 +405,7 @@ func commonFindPostBackend(ctxt ui.AmContext, comm *database.Community, conf *da
ctxt.VarMap().Set("resultShowNext", true) ctxt.VarMap().Set("resultShowNext", true)
} }
} }
return "framed_template", "find_posts.jet", nil return "framed", "find_posts.jet"
} }
/* FindPostsCommunity finds posts in a community. /* FindPostsCommunity finds posts in a community.
@@ -419,9 +414,8 @@ func commonFindPostBackend(ctxt ui.AmContext, comm *database.Community, conf *da
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func FindPostsCommunity(ctxt ui.AmContext) (string, any, error) { func FindPostsCommunity(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
ctxt.VarMap().Set("scope", "community") ctxt.VarMap().Set("scope", "community")
ctxt.VarMap().Set("entityName", comm.Name) ctxt.VarMap().Set("entityName", comm.Name)
@@ -436,9 +430,8 @@ func FindPostsCommunity(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func FindPostsConference(ctxt ui.AmContext) (string, any, error) { func FindPostsConference(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
ctxt.VarMap().Set("scope", "conference") ctxt.VarMap().Set("scope", "conference")
@@ -454,9 +447,8 @@ func FindPostsConference(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func FindPostsTopic(ctxt ui.AmContext) (string, any, error) { func FindPostsTopic(ctxt ui.AmContext) (string, any) {
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
topic := ctxt.GetScratch("currentTopic").(*database.Topic) topic := ctxt.GetScratch("currentTopic").(*database.Topic)
+19 -27
View File
@@ -12,7 +12,6 @@ package main
import ( import (
"errors" "errors"
"fmt" "fmt"
"net/http"
"net/mail" "net/mail"
"git.erbosoft.com/amy/amsterdam/database" "git.erbosoft.com/amy/amsterdam/database"
@@ -26,12 +25,10 @@ import (
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func InviteToCommunity(ctxt ui.AmContext) (string, any, error) { func InviteToCommunity(ctxt ui.AmContext) (string, any) {
if ctxt.CurrentUser().IsAnon { if ctxt.CurrentUser().IsAnon {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
@@ -40,7 +37,7 @@ func InviteToCommunity(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("subtitle", comm.Name) ctxt.VarMap().Set("subtitle", comm.Name)
ctxt.VarMap().Set("backlink", fmt.Sprintf("/comm/%s/profile", comm.Alias)) ctxt.VarMap().Set("backlink", fmt.Sprintf("/comm/%s/profile", comm.Alias))
ctxt.VarMap().Set("cid", fmt.Sprintf("%d", comm.Id)) ctxt.VarMap().Set("cid", fmt.Sprintf("%d", comm.Id))
return "framed_template", "invite.jet", nil return "framed", "invite.jet"
} }
/* InviteToConference displays the conference invitation form. /* InviteToConference displays the conference invitation form.
@@ -49,12 +46,10 @@ func InviteToCommunity(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func InviteToConference(ctxt ui.AmContext) (string, any, error) { func InviteToConference(ctxt ui.AmContext) (string, any) {
if ctxt.CurrentUser().IsAnon { if ctxt.CurrentUser().IsAnon {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
@@ -65,7 +60,7 @@ func InviteToConference(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("backlink", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias"))) ctxt.VarMap().Set("backlink", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias")))
ctxt.VarMap().Set("cid", fmt.Sprintf("%d", comm.Id)) ctxt.VarMap().Set("cid", fmt.Sprintf("%d", comm.Id))
ctxt.VarMap().Set("confid", fmt.Sprintf("%d", conf.ConfId)) ctxt.VarMap().Set("confid", fmt.Sprintf("%d", conf.ConfId))
return "framed_template", "invite.jet", nil return "framed", "invite.jet"
} }
/* InviteToTopic displays the topic invitation form. /* InviteToTopic displays the topic invitation form.
@@ -74,12 +69,10 @@ func InviteToConference(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func InviteToTopic(ctxt ui.AmContext) (string, any, error) { func InviteToTopic(ctxt ui.AmContext) (string, any) {
if ctxt.CurrentUser().IsAnon { if ctxt.CurrentUser().IsAnon {
ctxt.SetRC(http.StatusForbidden) return "error", ENOPERM
return ui.ErrorPage(ctxt, ENOPERM)
} }
comm := ctxt.CurrentCommunity() comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference) conf := ctxt.GetScratch("currentConference").(*database.Conference)
@@ -92,7 +85,7 @@ func InviteToTopic(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("cid", fmt.Sprintf("%d", comm.Id)) ctxt.VarMap().Set("cid", fmt.Sprintf("%d", comm.Id))
ctxt.VarMap().Set("confid", fmt.Sprintf("%d", conf.ConfId)) ctxt.VarMap().Set("confid", fmt.Sprintf("%d", conf.ConfId))
ctxt.VarMap().Set("topicid", fmt.Sprintf("%d", topic.TopicId)) ctxt.VarMap().Set("topicid", fmt.Sprintf("%d", topic.TopicId))
return "framed_template", "invite.jet", nil return "framed", "invite.jet"
} }
/* InviteSend is the back end that handles sending invitations. /* InviteSend is the back end that handles sending invitations.
@@ -101,14 +94,13 @@ func InviteToTopic(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func InviteSend(ctxt ui.AmContext) (string, any, error) { func InviteSend(ctxt ui.AmContext) (string, any) {
backlink := ctxt.FormField("backlink") backlink := ctxt.FormField("backlink")
if ctxt.FormFieldIsSet("cancel") { if ctxt.FormFieldIsSet("cancel") {
return "redirect", backlink, nil return "redirect", backlink
} else if !ctxt.FormFieldIsSet("send") { } else if !ctxt.FormFieldIsSet("send") {
return ui.ErrorPage(ctxt, errors.New("invalid command")) return "error", "invalid command"
} }
var comm *database.Community var comm *database.Community
if ctxt.FormFieldIsSet("cid") { if ctxt.FormFieldIsSet("cid") {
@@ -117,10 +109,10 @@ func InviteSend(ctxt ui.AmContext) (string, any, error) {
comm, err = database.AmGetCommunity(ctxt.Ctx(), int32(id)) comm, err = database.AmGetCommunity(ctxt.Ctx(), int32(id))
} }
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
} else { } else {
return ui.ErrorPage(ctxt, errors.New("no parameters specified")) return "error", "no parameters specified"
} }
mode := "community" mode := "community"
var conf *database.Conference = nil var conf *database.Conference = nil
@@ -138,7 +130,7 @@ func InviteSend(ctxt ui.AmContext) (string, any, error) {
} }
} }
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "errors", err
} }
if ctxt.FormFieldIsSet("topicid") { if ctxt.FormFieldIsSet("topicid") {
id, err := ctxt.FormFieldInt("topicid") id, err := ctxt.FormFieldInt("topicid")
@@ -149,7 +141,7 @@ func InviteSend(ctxt ui.AmContext) (string, any, error) {
} }
} }
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "errors", err
} }
mode = "topic" mode = "topic"
} else { } else {
@@ -159,12 +151,12 @@ func InviteSend(ctxt ui.AmContext) (string, any, error) {
addr := ctxt.FormField("addr") addr := ctxt.FormField("addr")
_, err := mail.ParseAddress(addr) _, err := mail.ParseAddress(addr)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "errors", err
} }
ci, err := database.AmGetContactInfoForUser(ctxt.Ctx(), ctxt.CurrentUserId()) ci, err := database.AmGetContactInfoForUser(ctxt.Ctx(), ctxt.CurrentUserId())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "errors", err
} }
mailMessage := email.AmNewEmailMessage(ctxt.CurrentUserId(), ctxt.RemoteIP()) mailMessage := email.AmNewEmailMessage(ctxt.CurrentUserId(), ctxt.RemoteIP())
@@ -183,5 +175,5 @@ func InviteSend(ctxt ui.AmContext) (string, any, error) {
mailMessage.AddVariable("username", ctxt.CurrentUser().Username) mailMessage.AddVariable("username", ctxt.CurrentUser().Username)
mailMessage.Send() mailMessage.Send()
return "redirect", backlink, nil return "redirect", backlink
} }
+38 -48
View File
@@ -11,7 +11,6 @@ package main
import ( import (
"errors" "errors"
"fmt"
"net/url" "net/url"
"time" "time"
@@ -28,9 +27,8 @@ import (
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func LoginForm(ctxt ui.AmContext) (string, any, error) { func LoginForm(ctxt ui.AmContext) (string, any) {
// Get target URI. // Get target URI.
target := ctxt.Parameter("tgt") target := ctxt.Parameter("tgt")
if target == "" { if target == "" {
@@ -39,7 +37,7 @@ func LoginForm(ctxt ui.AmContext) (string, any, error) {
// If user is already logged in, this is a no-op. // If user is already logged in, this is a no-op.
if !ctxt.CurrentUser().IsAnon { if !ctxt.CurrentUser().IsAnon {
return "redirect", target, nil return "redirect", target
} }
dlg, err := ui.AmLoadDialog("login") dlg, err := ui.AmLoadDialog("login")
@@ -47,7 +45,7 @@ func LoginForm(ctxt ui.AmContext) (string, any, error) {
dlg.Field("tgt").Value = target dlg.Field("tgt").Value = target
return dlg.Render(ctxt) return dlg.Render(ctxt)
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
/* Login handles logging in to Amsterdam. /* Login handles logging in to Amsterdam.
@@ -56,9 +54,8 @@ func LoginForm(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func Login(ctxt ui.AmContext) (string, any, error) { func Login(ctxt ui.AmContext) (string, any) {
dlg, err := ui.AmLoadDialog("login") dlg, err := ui.AmLoadDialog("login")
if err == nil { if err == nil {
dlg.LoadFromForm(ctxt) dlg.LoadFromForm(ctxt)
@@ -68,12 +65,12 @@ func Login(ctxt ui.AmContext) (string, any, error) {
} }
// If user is already logged in, this is a no-op. // If user is already logged in, this is a no-op.
if !ctxt.CurrentUser().IsAnon { if !ctxt.CurrentUser().IsAnon {
return "redirect", target, nil return "redirect", target
} }
action := dlg.WhichButton(ctxt) action := dlg.WhichButton(ctxt)
if action == "cancel" { // Cancel button pressed if action == "cancel" { // Cancel button pressed
return "redirect", target, nil return "redirect", target
} }
username := dlg.Field("user").Value // since the dialog won't check this for us username := dlg.Field("user").Value // since the dialog won't check this for us
if len(username) == 0 { if len(username) == 0 {
@@ -125,14 +122,14 @@ func Login(ctxt ui.AmContext) (string, any, error) {
} }
} }
if user.VerifyEMail { if user.VerifyEMail {
return "redirect", target, nil return "redirect", target
} else { } else {
return "redirect", "/verify?tgt=" + url.QueryEscape(target), nil return "redirect", "/verify?tgt=" + url.QueryEscape(target)
} }
} }
return dlg.RenderError(ctxt, "No known button click on POST to login function.") return dlg.RenderError(ctxt, "No known button click on POST to login function.")
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
/* Logout handles logging out from Amsterdam. /* Logout handles logging out from Amsterdam.
@@ -141,9 +138,8 @@ func Login(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func Logout(ctxt ui.AmContext) (string, any, error) { func Logout(ctxt ui.AmContext) (string, any) {
// Get target URI. // Get target URI.
target := ctxt.Parameter("tgt") target := ctxt.Parameter("tgt")
if target == "" { if target == "" {
@@ -154,7 +150,7 @@ func Logout(ctxt ui.AmContext) (string, any, error) {
ctxt.ClearLoginCookie() ctxt.ClearLoginCookie()
ctxt.ClearSession() ctxt.ClearSession()
} }
return "redirect", target, nil return "redirect", target
} }
/* VerifyEmailForm renders the E-mail address verification form. /* VerifyEmailForm renders the E-mail address verification form.
@@ -163,9 +159,8 @@ func Logout(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func VerifyEmailForm(ctxt ui.AmContext) (string, any, error) { func VerifyEmailForm(ctxt ui.AmContext) (string, any) {
// Get target URI. // Get target URI.
target := ctxt.Parameter("tgt") target := ctxt.Parameter("tgt")
if target == "" { if target == "" {
@@ -175,12 +170,12 @@ func VerifyEmailForm(ctxt ui.AmContext) (string, any, error) {
// If user is not logged in, this is an error. // If user is not logged in, this is an error.
user := ctxt.CurrentUser() user := ctxt.CurrentUser()
if user.IsAnon { if user.IsAnon {
return ui.ErrorPage(ctxt, errors.New("you must log in before you can verify your account's E-mail address")) return "error", "you must log in before you can verify your account's E-mail address"
} }
// If user is already verified, this is a no-op. // If user is already verified, this is a no-op.
if user.VerifyEMail { if user.VerifyEMail {
return "redirect", target, nil return "redirect", target
} }
dlg, err := ui.AmLoadDialog("verify_email") dlg, err := ui.AmLoadDialog("verify_email")
@@ -188,7 +183,7 @@ func VerifyEmailForm(ctxt ui.AmContext) (string, any, error) {
dlg.Field("tgt").Value = target dlg.Field("tgt").Value = target
return dlg.Render(ctxt) return dlg.Render(ctxt)
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
// sendEmailConfirmationEmail sends the "E-mail confirmation number" E-mail message. // sendEmailConfirmationEmail sends the "E-mail confirmation number" E-mail message.
@@ -212,13 +207,12 @@ func sendEmailConfirmationEmail(user *database.User, ci *database.ContactInfo, r
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func VerifyEMail(ctxt ui.AmContext) (string, any, error) { func VerifyEMail(ctxt ui.AmContext) (string, any) {
// If user is not logged in, this is an error. // If user is not logged in, this is an error.
user := ctxt.CurrentUser() user := ctxt.CurrentUser()
if user.IsAnon { if user.IsAnon {
return ui.ErrorPage(ctxt, errors.New("you must log in before you can verify your account's E-mail address")) return "error", "you must log in before you can verify your account's E-mail address"
} }
dlg, err := ui.AmLoadDialog("verify_email") dlg, err := ui.AmLoadDialog("verify_email")
@@ -231,12 +225,12 @@ func VerifyEMail(ctxt ui.AmContext) (string, any, error) {
// If user is already verified, this is a no-op. // If user is already verified, this is a no-op.
if user.VerifyEMail { if user.VerifyEMail {
return "redirect", target, nil return "redirect", target
} }
action := dlg.WhichButton(ctxt) action := dlg.WhichButton(ctxt)
if action == "cancel" { // Cancel button pressed if action == "cancel" { // Cancel button pressed
return "redirect", target, nil return "redirect", target
} }
if action == "sendagain" { if action == "sendagain" {
var ci *database.ContactInfo var ci *database.ContactInfo
@@ -259,14 +253,14 @@ func VerifyEMail(ctxt ui.AmContext) (string, any, error) {
cn, _ := dlg.Field("num").ValueInt() cn, _ := dlg.Field("num").ValueInt()
err = user.ConfirmEMailAddress(ctxt.Ctx(), int32(cn), ctxt.RemoteIP()) err = user.ConfirmEMailAddress(ctxt.Ctx(), int32(cn), ctxt.RemoteIP())
if err == nil { if err == nil {
return "redirect", target, nil return "redirect", target
} }
} }
return dlg.RenderError(ctxt, err.Error()) return dlg.RenderError(ctxt, err.Error())
} }
return dlg.RenderError(ctxt, "No known button click on POST to verify function.") return dlg.RenderError(ctxt, "No known button click on POST to verify function.")
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
/* NewAccountUserAgreement renders the Amsterdam user agreement for new accounts. /* NewAccountUserAgreement renders the Amsterdam user agreement for new accounts.
@@ -275,9 +269,8 @@ func VerifyEMail(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func NewAccountUserAgreement(ctxt ui.AmContext) (string, any, error) { func NewAccountUserAgreement(ctxt ui.AmContext) (string, any) {
// Get target URI. // Get target URI.
target := ctxt.Parameter("tgt") target := ctxt.Parameter("tgt")
if target == "" { if target == "" {
@@ -286,14 +279,14 @@ func NewAccountUserAgreement(ctxt ui.AmContext) (string, any, error) {
// If user is already logged in, this is an error. // If user is already logged in, this is an error.
if !ctxt.CurrentUser().IsAnon { if !ctxt.CurrentUser().IsAnon {
return ui.ErrorPage(ctxt, errors.New("you cannot create a new account while logged in on an existing one. You must log out first")) return "error", "you cannot create a new account while logged in on an existing one. You must log out first"
} }
ctxt.SetLeftMenu("top") ctxt.SetLeftMenu("top")
ctxt.VarMap().Set("target", target) ctxt.VarMap().Set("target", target)
ctxt.VarMap().Set("amsterdam_pageTitle", "New Account User Agreement") ctxt.VarMap().Set("amsterdam_pageTitle", "New Account User Agreement")
ctxt.VarMap().Set("amsterdam_suppressLogin", true) ctxt.VarMap().Set("amsterdam_suppressLogin", true)
return "framed_template", "agreement.jet", nil return "framed", "agreement.jet"
} }
/* NewAccountUserAgreement renders the Amsterdam account creation form. /* NewAccountUserAgreement renders the Amsterdam account creation form.
@@ -302,9 +295,8 @@ func NewAccountUserAgreement(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func NewAccountForm(ctxt ui.AmContext) (string, any, error) { func NewAccountForm(ctxt ui.AmContext) (string, any) {
// Get target URI. // Get target URI.
target := ctxt.Parameter("tgt") target := ctxt.Parameter("tgt")
if target == "" { if target == "" {
@@ -313,7 +305,7 @@ func NewAccountForm(ctxt ui.AmContext) (string, any, error) {
// If user is already logged in, this is an error. // If user is already logged in, this is an error.
if !ctxt.CurrentUser().IsAnon { if !ctxt.CurrentUser().IsAnon {
return ui.ErrorPage(ctxt, fmt.Errorf("you cannot create a new account while logged in on an existing one. You must log out first")) return "error", "you cannot create a new account while logged in on an existing one. You must log out first"
} }
dlg, err := ui.AmLoadDialog("newaccount") dlg, err := ui.AmLoadDialog("newaccount")
@@ -322,7 +314,7 @@ func NewAccountForm(ctxt ui.AmContext) (string, any, error) {
dlg.Field("country").Value = "XX" dlg.Field("country").Value = "XX"
return dlg.Render(ctxt) return dlg.Render(ctxt)
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
/* NewAccount handles creating a new Amsterdam account. /* NewAccount handles creating a new Amsterdam account.
@@ -331,12 +323,11 @@ func NewAccountForm(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func NewAccount(ctxt ui.AmContext) (string, any, error) { func NewAccount(ctxt ui.AmContext) (string, any) {
// If user is already logged in, this is an error. // If user is already logged in, this is an error.
if !ctxt.CurrentUser().IsAnon { if !ctxt.CurrentUser().IsAnon {
return ui.ErrorPage(ctxt, fmt.Errorf("you cannot create a new account while logged in on an existing one. You must log out first")) return "error", "you cannot create a new account while logged in on an existing one. You must log out first"
} }
dlg, err := ui.AmLoadDialog("newaccount") dlg, err := ui.AmLoadDialog("newaccount")
@@ -349,7 +340,7 @@ func NewAccount(ctxt ui.AmContext) (string, any, error) {
action := dlg.WhichButton(ctxt) action := dlg.WhichButton(ctxt)
if action == "cancel" { // Cancel button pressed if action == "cancel" { // Cancel button pressed
return "redirect", target, nil return "redirect", target
} }
if action == "create" { if action == "create" {
err = dlg.Validate() err = dlg.Validate()
@@ -394,7 +385,7 @@ func NewAccount(ctxt ui.AmContext) (string, any, error) {
if err == nil { if err == nil {
// user is now logged in! redirect to E-mail verification // user is now logged in! redirect to E-mail verification
ctxt.ReplaceUser(user) ctxt.ReplaceUser(user)
return "redirect", "/verify?tgt=" + url.QueryEscape(target), nil return "redirect", "/verify?tgt=" + url.QueryEscape(target)
} }
} }
} }
@@ -403,7 +394,7 @@ func NewAccount(ctxt ui.AmContext) (string, any, error) {
} }
return dlg.RenderError(ctxt, "No known button click on POST to new account.") return dlg.RenderError(ctxt, "No known button click on POST to new account.")
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
/* PasswordRecovery handles a click on a "password recovery" link to fix the user's password. /* PasswordRecovery handles a click on a "password recovery" link to fix the user's password.
@@ -412,9 +403,8 @@ func NewAccount(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func PasswordRecovery(ctxt ui.AmContext) (string, any, error) { func PasswordRecovery(ctxt ui.AmContext) (string, any) {
var emailaddy string var emailaddy string
uid, err := ctxt.URLParamInt("uid") uid, err := ctxt.URLParamInt("uid")
if err == nil { if err == nil {
@@ -422,13 +412,13 @@ func PasswordRecovery(ctxt ui.AmContext) (string, any, error) {
if err == nil { if err == nil {
pchange := database.AmGetPasswordChangeRequest(int32(uid)) pchange := database.AmGetPasswordChangeRequest(int32(uid))
if pchange == nil { if pchange == nil {
return ui.ErrorPage(ctxt, errors.New("password change request not found")) return "error", "password change request not found"
} }
if auth != int(pchange.Authentication) { if auth != int(pchange.Authentication) {
return ui.ErrorPage(ctxt, errors.New("invalid password change request")) return "error", "invalid password change request"
} }
if time.Now().Compare(pchange.Expires) > 0 { if time.Now().Compare(pchange.Expires) > 0 {
return ui.ErrorPage(ctxt, errors.New("password change request has expired")) return "error", "password change request has expired"
} }
emailaddy = pchange.Email emailaddy = pchange.Email
} }
@@ -449,9 +439,9 @@ func PasswordRecovery(ctxt ui.AmContext) (string, any, error) {
msg.Send() msg.Send()
ctxt.SetLeftMenu("top") ctxt.SetLeftMenu("top")
ctxt.VarMap().Set("amsterdam_pageTitle", "Your Password Has Been Changed") ctxt.VarMap().Set("amsterdam_pageTitle", "Your Password Has Been Changed")
return "framed_template", "password_changed.jet", nil return "framed_template", "password_changed.jet"
} }
} }
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
+3 -8
View File
@@ -11,9 +11,6 @@
package main package main
import ( import (
"errors"
"net/http"
"git.erbosoft.com/amy/amsterdam/database" "git.erbosoft.com/amy/amsterdam/database"
"git.erbosoft.com/amy/amsterdam/ui" "git.erbosoft.com/amy/amsterdam/ui"
) )
@@ -24,17 +21,15 @@ import (
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func SysAdminMenu(ctxt ui.AmContext) (string, any, error) { func SysAdminMenu(ctxt ui.AmContext) (string, any) {
u := ctxt.CurrentUser() u := ctxt.CurrentUser()
if !database.AmTestPermission("Global.SysAdminAccess", u.BaseLevel) { if !database.AmTestPermission("Global.SysAdminAccess", u.BaseLevel) {
ctxt.SetRC(http.StatusForbidden) return "error", ENOACCESS
return ui.ErrorPage(ctxt, errors.New("you are not authorized access to this page"))
} }
menu := ui.AmMenu("sysadmin") menu := ui.AmMenu("sysadmin")
ctxt.VarMap().Set("menu", menu) ctxt.VarMap().Set("menu", menu)
ctxt.VarMap().Set("defs", make(map[string]bool)) ctxt.VarMap().Set("defs", make(map[string]bool))
ctxt.VarMap().Set("amsterdam_pageTitle", menu.Title) ctxt.VarMap().Set("amsterdam_pageTitle", menu.Title)
return "framed_template", "menu.jet", nil return "framed", "menu.jet"
} }
+14 -18
View File
@@ -17,6 +17,7 @@ import (
"git.erbosoft.com/amy/amsterdam/database" "git.erbosoft.com/amy/amsterdam/database"
"git.erbosoft.com/amy/amsterdam/ui" "git.erbosoft.com/amy/amsterdam/ui"
"github.com/CloudyKit/jet/v6" "github.com/CloudyKit/jet/v6"
"github.com/labstack/echo/v4"
) )
// RenderedSideboxItem is an item for display inside a rendered sidebox. // RenderedSideboxItem is an item for display inside a rendered sidebox.
@@ -232,16 +233,15 @@ func templateTopicLink(args jet.Arguments) reflect.Value {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func TopPage(ctxt ui.AmContext) (string, any, error) { func TopPage(ctxt ui.AmContext) (string, any) {
// Set the page title. // Set the page title.
ctxt.VarMap().Set("amsterdam_pageTitle", "My Front Page") ctxt.VarMap().Set("amsterdam_pageTitle", "My Front Page")
// Retrieve the published posts. // Retrieve the published posts.
hdrs, err := database.AmGetPublishedPosts(ctxt.Ctx()) hdrs, err := database.AmGetPublishedPosts(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
ctxt.VarMap().Set("posts", hdrs) ctxt.VarMap().Set("posts", hdrs)
@@ -254,14 +254,14 @@ func TopPage(ctxt ui.AmContext) (string, any, error) {
uid := ctxt.CurrentUserId() uid := ctxt.CurrentUserId()
sboxes, err := database.AmGetSideboxes(ctxt.Ctx(), uid) sboxes, err := database.AmGetSideboxes(ctxt.Ctx(), uid)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
rc := make([]RenderedSidebox, len(sboxes)) rc := make([]RenderedSidebox, len(sboxes))
for i, sb := range sboxes { for i, sb := range sboxes {
err = buildRenderedSidebox(ctxt, uid, &(rc[i]), sb) err = buildRenderedSidebox(ctxt, uid, &(rc[i]), sb)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
} }
ctxt.VarMap().Set("sideboxes", rc) ctxt.VarMap().Set("sideboxes", rc)
@@ -269,7 +269,7 @@ func TopPage(ctxt ui.AmContext) (string, any, error) {
// Final data set. // Final data set.
ctxt.SetLeftMenu("top") ctxt.SetLeftMenu("top")
ctxt.VarMap().Set("amsterdam_genRefresh", true) ctxt.VarMap().Set("amsterdam_genRefresh", true)
return "framed_template", "top.jet", nil return "framed", "top.jet"
} }
/* AboutPage renders the "About Amsterdam" page. /* AboutPage renders the "About Amsterdam" page.
@@ -278,12 +278,11 @@ func TopPage(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func AboutPage(ctxt ui.AmContext) (string, any, error) { func AboutPage(ctxt ui.AmContext) (string, any) {
// Set the page title. // Set the page title.
ctxt.VarMap().Set("amsterdam_pageTitle", "About Amsterdam") ctxt.VarMap().Set("amsterdam_pageTitle", "About Amsterdam")
return "framed_template", "about.jet", nil return "framed", "about.jet"
} }
/* JumpToShortcut resolves "/go" links by redirecting them to the appropriate page. /* JumpToShortcut resolves "/go" links by redirecting them to the appropriate page.
@@ -292,22 +291,19 @@ func AboutPage(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func JumpToShortcut(ctxt ui.AmContext) (string, any, error) { func JumpToShortcut(ctxt ui.AmContext) (string, any) {
link, err := database.AmDecodePostLink(ctxt.URLParam("postlink")) link, err := database.AmDecodePostLink(ctxt.URLParam("postlink"))
if err != nil { if err != nil {
ctxt.SetRC(http.StatusNotFound) return "error", echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("not found: %s", ctxt.URLParam("postlink"))).SetInternal(err)
return ui.ErrorPage(ctxt, fmt.Errorf("not found: %s (%v)", ctxt.URLParam("postlink"), err))
} }
scope, target := link.Classify() scope, target := link.Classify()
if scope != "global" { if scope != "global" {
ctxt.SetRC(http.StatusNotFound) ctxt.SetRC(http.StatusNotFound)
return ui.ErrorPage(ctxt, fmt.Errorf("not found: %s", ctxt.URLParam("postlink"))) return "error", echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("not found: %s", ctxt.URLParam("postlink")))
} }
if err = link.VerifyNames(ctxt.Ctx()); err != nil { if err = link.VerifyNames(ctxt.Ctx()); err != nil {
ctxt.SetRC(http.StatusNotFound) return "error", echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("not found: %s", ctxt.URLParam("postlink"))).SetInternal(err)
return ui.ErrorPage(ctxt, fmt.Errorf("not found: %s (%v)", ctxt.URLParam("postlink"), err))
} }
targetURL := "" targetURL := ""
switch target { switch target {
@@ -320,7 +316,7 @@ func JumpToShortcut(ctxt ui.AmContext) (string, any, error) {
case "post", "postrange", "postopenrange": case "post", "postrange", "postopenrange":
targetURL = fmt.Sprintf("/comm/%s/conf/%s/r/%d?r=%d,%d", link.Community, link.Conference, link.Topic, link.FirstPost, link.LastPost) targetURL = fmt.Sprintf("/comm/%s/conf/%s/r/%d?r=%d,%d", link.Community, link.Conference, link.Topic, link.FirstPost, link.LastPost)
default: default:
return ui.ErrorPage(ctxt, fmt.Errorf("invalid target '%s' for link: %s", target, ctxt.URLParam("postlink"))) return "error", fmt.Sprintf("invalid target '%s' for link: %s", target, ctxt.URLParam("postlink"))
} }
return "redirect", targetURL, nil return "redirect", targetURL
} }
+4 -7
View File
@@ -261,9 +261,8 @@ func (d *Dialog) Field(name string) *DialogItem {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func (d *Dialog) Render(ctxt AmContext) (string, any, error) { func (d *Dialog) Render(ctxt AmContext) (string, any) {
required := false required := false
for i, fld := range d.Fields { for i, fld := range d.Fields {
if fld.Required { if fld.Required {
@@ -323,7 +322,7 @@ func (d *Dialog) Render(ctxt AmContext) (string, any, error) {
if strings.Contains(d.Options, "suppresslogin") { if strings.Contains(d.Options, "suppresslogin") {
ctxt.VarMap().Set("amsterdam_suppressLogin", true) ctxt.VarMap().Set("amsterdam_suppressLogin", true)
} }
return "framed_template", "dialog.jet", nil return "framed", "dialog.jet"
} }
/* RenderError sets up the rendering parameters to send this dialog to the output with an error message. /* RenderError sets up the rendering parameters to send this dialog to the output with an error message.
@@ -333,9 +332,8 @@ func (d *Dialog) Render(ctxt AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func (d *Dialog) RenderError(ctxt AmContext, errormessage string) (string, any, error) { func (d *Dialog) RenderError(ctxt AmContext, errormessage string) (string, any) {
ctxt.VarMap().Set("amsterdam_errorMessage", errormessage) ctxt.VarMap().Set("amsterdam_errorMessage", errormessage)
return d.Render(ctxt) return d.Render(ctxt)
} }
@@ -347,9 +345,8 @@ func (d *Dialog) RenderError(ctxt AmContext, errormessage string) (string, any,
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func (d *Dialog) RenderInfo(ctxt AmContext, infoMessage string) (string, any, error) { func (d *Dialog) RenderInfo(ctxt AmContext, infoMessage string) (string, any) {
ctxt.VarMap().Set("amsterdam_infoMessage", infoMessage) ctxt.VarMap().Set("amsterdam_infoMessage", infoMessage)
return d.Render(ctxt) return d.Render(ctxt)
} }
+2 -2
View File
@@ -103,7 +103,7 @@ func (mb *MessageBox) SetLink(id, link string) {
} }
// Render sets up to render the message box. // Render sets up to render the message box.
func (mb *MessageBox) Render(ctxt AmContext) (string, any, error) { func (mb *MessageBox) Render(ctxt AmContext) (string, any) {
blinks := mb.buttonLinks blinks := mb.buttonLinks
if mb.def.useConfirm { if mb.def.useConfirm {
nonce := util.GenerateRandomAuthString() nonce := util.GenerateRandomAuthString()
@@ -133,7 +133,7 @@ func (mb *MessageBox) Render(ctxt AmContext) (string, any, error) {
ctxt.VarMap().Set("warningLines", mb.def.WarningLines) ctxt.VarMap().Set("warningLines", mb.def.WarningLines)
ctxt.VarMap().Set("buttons", mb.def.Buttons) ctxt.VarMap().Set("buttons", mb.def.Buttons)
ctxt.VarMap().Set("buttonLinks", blinks) ctxt.VarMap().Set("buttonLinks", blinks)
return "framed_template", "messagebox.jet", nil return "framed_template", "messagebox.jet"
} }
// Validate validates that the correct button was clicked by verifying the confirmation parameter. // Validate validates that the correct button was clicked by verifying the confirmation parameter.
+59 -27
View File
@@ -37,6 +37,44 @@ import (
*/ */
func AmSendPageData(ctxt echo.Context, amctxt AmContext, command string, data any) error { func AmSendPageData(ctxt echo.Context, amctxt AmContext, command string, data any) error {
var err error var err error
if command == "error" {
httprc := amctxt.RC()
message := ""
if data == nil {
message = fmt.Sprintf("Unspecified error in %s", ctxt.Request().URL.String())
} else if he, ok := data.(*echo.HTTPError); ok {
httprc = he.Code
m1 := he.Message
e1 := he.Unwrap()
if m1 == nil || m1 == "" {
if e1 == nil {
message = fmt.Sprintf("Unspecified error in %s", ctxt.Request().URL.String())
} else {
message = e1.Error()
}
} else {
if e1 == nil {
message = fmt.Sprintf("%v", m1)
} else {
message = fmt.Sprintf("%v (%v)", m1, e1)
}
}
} else if er, ok := data.(error); ok {
message = er.Error()
} else {
message = fmt.Sprintf("%v", data)
}
if httprc < 400 {
httprc = http.StatusInternalServerError
}
amctxt.VarMap().Set("amsterdam_pageTitle", "Internal Server Error")
amctxt.VarMap().Set("error", message)
amctxt.SetRC(httprc)
command = "framed"
data = "error.jet"
}
switch command { switch command {
case "bytes": case "bytes":
err = ctxt.Blob(amctxt.RC(), amctxt.OutputType(), data.([]byte)) err = ctxt.Blob(amctxt.RC(), amctxt.OutputType(), data.([]byte))
@@ -46,7 +84,7 @@ func AmSendPageData(ctxt echo.Context, amctxt AmContext, command string, data an
err = ctxt.String(amctxt.RC(), data.(string)) err = ctxt.String(amctxt.RC(), data.(string))
case "template": case "template":
err = ctxt.Render(amctxt.RC(), data.(string), amctxt) err = ctxt.Render(amctxt.RC(), data.(string), amctxt)
case "framed_template": case "framed", "framed_template":
amctxt.VarMap().Set("amsterdam_innerPage", data) amctxt.VarMap().Set("amsterdam_innerPage", data)
menus := make([]*MenuDefinition, 2) menus := make([]*MenuDefinition, 2)
switch amctxt.LeftMenu() { switch amctxt.LeftMenu() {
@@ -59,16 +97,16 @@ func AmSendPageData(ctxt echo.Context, amctxt AmContext, command string, data an
} }
menus[0] = md menus[0] = md
default: default:
return fmt.Errorf("unknown left menu context: %s", amctxt.LeftMenu()) return fmt.Errorf("AmSendPageData(): unknown left menu context: %s", amctxt.LeftMenu())
} }
menus[1] = AmMenu("fixed") menus[1] = AmMenu("fixed")
amctxt.VarMap().Set("amsterdam_leftMenus", menus) amctxt.VarMap().Set("amsterdam_leftMenus", menus)
err = ctxt.Render(amctxt.RC(), "frame.jet", amctxt) err = ctxt.Render(amctxt.RC(), "frame.jet", amctxt)
default: default:
err = fmt.Errorf("unknown rendering type: %s", command) err = fmt.Errorf("AmSendPageData(): unknown rendering type: %s", command)
} }
if err != nil { if err != nil {
log.Errorf("sendPageData() barfed with %v", err) log.Errorf("AmSendPageData() barfed with %v", err)
} }
return err return err
} }
@@ -94,6 +132,8 @@ func ErrorPage(ctxt AmContext, input_err error) (string, any, error) {
// expireTime is the expiration time sent in the dynamic headers. // expireTime is the expiration time sent in the dynamic headers.
var expireTime string = lctime.Strftime("%c", time.Unix(1, 0)) var expireTime string = lctime.Strftime("%c", time.Unix(1, 0))
type PageFunc func(AmContext) (string, any)
/* AmWrap wraps the Amsterdam handler function in a wrapper that implements the spec for /* AmWrap wraps the Amsterdam handler function in a wrapper that implements the spec for
* Echo handler functions. * Echo handler functions.
* Parameters: * Parameters:
@@ -101,33 +141,25 @@ var expireTime string = lctime.Strftime("%c", time.Unix(1, 0))
* Returns: * Returns:
* The wrapped function. * The wrapped function.
*/ */
func AmWrap(myfunc func(AmContext) (string, any, error)) echo.HandlerFunc { func AmWrap(myfunc PageFunc) echo.HandlerFunc {
return func(ctxt echo.Context) error { return func(c echo.Context) error {
amctxt := AmContextFromEchoContext(ctxt) ctxt := AmContextFromEchoContext(c)
// Add the dynamic headers. // Add the dynamic headers.
ctxt.Response().Header().Set("Pragma", "No-cache") c.Response().Header().Set("Pragma", "No-cache")
ctxt.Response().Header().Set("Cache-Control", "no-cache") c.Response().Header().Set("Cache-Control", "no-cache")
ctxt.Response().Header().Set("Expires", expireTime) c.Response().Header().Set("Expires", expireTime)
// Exec the wrapped function. // Exec the wrapped function.
what, rc, err := myfunc(amctxt) command, arg := myfunc(ctxt)
if err == nil { if err := ctxt.SaveSession(); err != nil {
if err = amctxt.SaveSession(); err != nil { c.Logger().Errorf("Session save error: %v", err)
ctxt.Logger().Errorf("Session save error: %v", err) return err
return err
}
err = AmSendPageData(ctxt, amctxt, what, rc)
if err != nil {
ctxt.Logger().Errorf("Rendering error: %v", err)
}
} else {
ctxt.Logger().Errorf("Page function error: %v", err)
_, rc, _ = ErrorPage(amctxt, err)
amctxt.SetRC(http.StatusInternalServerError)
newerr := AmSendPageData(ctxt, amctxt, "framed_template", rc)
err = newerr
} }
return err if err := AmSendPageData(c, ctxt, command, arg); err != nil {
c.Logger().Errorf("Rendering error: %v", err)
return err
}
return nil
} }
} }
+46 -53
View File
@@ -23,6 +23,7 @@ import (
"git.erbosoft.com/amy/amsterdam/ui" "git.erbosoft.com/amy/amsterdam/ui"
"git.erbosoft.com/amy/amsterdam/util" "git.erbosoft.com/amy/amsterdam/util"
"github.com/biter777/countries" "github.com/biter777/countries"
"github.com/labstack/echo/v4"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@@ -40,9 +41,8 @@ func userPhotoURL(ci *database.ContactInfo) string {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func EditProfileForm(ctxt ui.AmContext) (string, any, error) { func EditProfileForm(ctxt ui.AmContext) (string, any) {
// Get target URI. // Get target URI.
target := ctxt.Parameter("tgt") target := ctxt.Parameter("tgt")
if target == "" { if target == "" {
@@ -50,7 +50,7 @@ func EditProfileForm(ctxt ui.AmContext) (string, any, error) {
} }
u := ctxt.CurrentUser() u := ctxt.CurrentUser()
if u.IsAnon { if u.IsAnon {
return ui.ErrorPage(ctxt, errors.New("you are not logged in")) return "error", "you are not logged in"
} }
dlg, err := ui.AmLoadDialog("profile") dlg, err := ui.AmLoadDialog("profile")
if err == nil { if err == nil {
@@ -95,7 +95,7 @@ func EditProfileForm(ctxt ui.AmContext) (string, any, error) {
} }
} }
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
/* EditProfile handles profile editing. /* EditProfile handles profile editing.
@@ -104,12 +104,11 @@ func EditProfileForm(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func EditProfile(ctxt ui.AmContext) (string, any, error) { func EditProfile(ctxt ui.AmContext) (string, any) {
u := ctxt.CurrentUser() u := ctxt.CurrentUser()
if u.IsAnon { if u.IsAnon {
return ui.ErrorPage(ctxt, errors.New("you are not logged in")) return "error", "you are not logged in"
} }
dlg, err := ui.AmLoadDialog("profile") dlg, err := ui.AmLoadDialog("profile")
if err == nil { if err == nil {
@@ -122,7 +121,7 @@ func EditProfile(ctxt ui.AmContext) (string, any, error) {
action := dlg.WhichButton(ctxt) action := dlg.WhichButton(ctxt)
if action == "cancel" { // Cancel button pressed if action == "cancel" { // Cancel button pressed
return "redirect", target, nil return "redirect", target
} }
if action == "update" { if action == "update" {
err = dlg.Validate() err = dlg.Validate()
@@ -192,17 +191,17 @@ func EditProfile(ctxt ui.AmContext) (string, any, error) {
if emailChange { if emailChange {
err = sendEmailConfirmationEmail(u, ci, ctxt.RemoteIP()) err = sendEmailConfirmationEmail(u, ci, ctxt.RemoteIP())
if err == nil { if err == nil {
return "redirect", "/verify?tgt=" + url.QueryEscape(target), nil return "redirect", "/verify?tgt=" + url.QueryEscape(target)
} }
} else { } else {
return "redirect", target, nil return "redirect", target
} }
} }
} }
} }
return dlg.RenderError(ctxt, "No known button click on POST to profile.") return dlg.RenderError(ctxt, "No known button click on POST to profile.")
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
/* ProfilePhotoForm renders the Amsterdam profile photo upload form. /* ProfilePhotoForm renders the Amsterdam profile photo upload form.
@@ -211,9 +210,8 @@ func EditProfile(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func ProfilePhotoForm(ctxt ui.AmContext) (string, any, error) { func ProfilePhotoForm(ctxt ui.AmContext) (string, any) {
// Get target URI. // Get target URI.
target := ctxt.Parameter("tgt") target := ctxt.Parameter("tgt")
if target == "" { if target == "" {
@@ -221,7 +219,7 @@ func ProfilePhotoForm(ctxt ui.AmContext) (string, any, error) {
} }
u := ctxt.CurrentUser() u := ctxt.CurrentUser()
if u.IsAnon { if u.IsAnon {
return ui.ErrorPage(ctxt, errors.New("you are not logged in")) return "error", "you are not logged in"
} }
ci, err := u.ContactInfo(ctxt.Ctx()) ci, err := u.ContactInfo(ctxt.Ctx())
if err == nil { if err == nil {
@@ -229,9 +227,9 @@ func ProfilePhotoForm(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("photo_url", userPhotoURL(ci)) ctxt.VarMap().Set("photo_url", userPhotoURL(ci))
ctxt.VarMap().Set("amsterdam_pageTitle", "Upload User Photo") ctxt.VarMap().Set("amsterdam_pageTitle", "Upload User Photo")
ctxt.VarMap().Set("amsterdam_suppressLogin", true) ctxt.VarMap().Set("amsterdam_suppressLogin", true)
return "framed_template", "photo_upload.jet", nil return "framed", "photo_upload.jet"
} }
return ui.ErrorPage(ctxt, err) return "error", err
} }
/* ProfilePhoto handles processing the uploaded user photo. /* ProfilePhoto handles processing the uploaded user photo.
@@ -240,23 +238,22 @@ func ProfilePhotoForm(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func ProfilePhoto(ctxt ui.AmContext) (string, any, error) { func ProfilePhoto(ctxt ui.AmContext) (string, any) {
u := ctxt.CurrentUser() u := ctxt.CurrentUser()
if u.IsAnon { if u.IsAnon {
return ui.ErrorPage(ctxt, errors.New("you are not logged in")) return "error", "you are not logged in"
} }
ci, err := u.ContactInfo(ctxt.Ctx()) ci, err := u.ContactInfo(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
target := ctxt.FormField("tgt") target := ctxt.FormField("tgt")
if target == "" { if target == "" {
target = "/" target = "/"
} }
if ctxt.FormFieldIsSet("cancel") { if ctxt.FormFieldIsSet("cancel") {
return "redirect", "/profile?tgt=" + url.QueryEscape(target), nil return "redirect", "/profile?tgt=" + url.QueryEscape(target)
} }
if ctxt.FormFieldIsSet("upload") { if ctxt.FormFieldIsSet("upload") {
file, err := ctxt.FormFile("thepic") file, err := ctxt.FormFile("thepic")
@@ -273,7 +270,7 @@ func ProfilePhoto(ctxt ui.AmContext) (string, any, error) {
ci.PhotoURL = &photourl ci.PhotoURL = &photourl
_, err = ci.Save(ctxt.Ctx()) _, err = ci.Save(ctxt.Ctx())
if err == nil { if err == nil {
return "redirect", "/profile?tgt=" + url.QueryEscape(target), nil return "redirect", "/profile?tgt=" + url.QueryEscape(target)
} }
} }
} }
@@ -283,19 +280,19 @@ func ProfilePhoto(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("photo_url", userPhotoURL(ci)) ctxt.VarMap().Set("photo_url", userPhotoURL(ci))
ctxt.VarMap().Set("amsterdam_pageTitle", "Upload User Photo") ctxt.VarMap().Set("amsterdam_pageTitle", "Upload User Photo")
ctxt.VarMap().Set("amsterdam_suppressLogin", true) ctxt.VarMap().Set("amsterdam_suppressLogin", true)
return "framed_template", "photo_upload.jet", nil return "framed", "photo_upload.jet"
} }
if ctxt.FormFieldIsSet("remove") { if ctxt.FormFieldIsSet("remove") {
purl := ci.PhotoURL purl := ci.PhotoURL
happy := false happy := false
if purl == nil || *purl == "" { if purl == nil || *purl == "" {
// this is a no-op // this is a no-op
return "redirect", "/profile?tgt=" + url.QueryEscape(target), nil return "redirect", "/profile?tgt=" + url.QueryEscape(target)
} }
if strings.HasPrefix(*purl, "/img/store/") { if strings.HasPrefix(*purl, "/img/store/") {
id, err := strconv.Atoi((*purl)[11:]) id, err := strconv.Atoi((*purl)[11:])
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
defer func() { defer func() {
if happy { if happy {
@@ -311,12 +308,12 @@ func ProfilePhoto(ctxt ui.AmContext) (string, any, error) {
ci.PhotoURL = nil ci.PhotoURL = nil
_, err := ci.Save(ctxt.Ctx()) _, err := ci.Save(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
happy = true happy = true
return "redirect", "/profile?tgt=" + url.QueryEscape(target), nil return "redirect", "/profile?tgt=" + url.QueryEscape(target)
} }
return ui.ErrorPage(ctxt, errors.New("invalid button detected in photo upload")) return "error", "invalid button detected in photo upload"
} }
/* ShowProfile displays a user's profile. /* ShowProfile displays a user's profile.
@@ -325,24 +322,22 @@ func ProfilePhoto(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func ShowProfile(ctxt ui.AmContext) (string, any, error) { func ShowProfile(ctxt ui.AmContext) (string, any) {
me := ctxt.CurrentUser() me := ctxt.CurrentUser()
prefs, err := me.Prefs(ctxt.Ctx()) prefs, err := me.Prefs(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
// Gather the info on the current user. // Gather the info on the current user.
user, err := database.AmGetUserByName(ctxt.Ctx(), ctxt.URLParam("uname"), nil) user, err := database.AmGetUserByName(ctxt.Ctx(), ctxt.URLParam("uname"), nil)
if err != nil { if err != nil {
ctxt.SetRC(http.StatusNotFound) return "error", echo.NewHTTPError(http.StatusNotFound).SetInternal(err)
return ui.ErrorPage(ctxt, err)
} }
ci, err := user.ContactInfo(ctxt.Ctx()) ci, err := user.ContactInfo(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
var pvtAddr, pvtPhone, pvtFax, pvtEmail bool var pvtAddr, pvtPhone, pvtFax, pvtEmail bool
if database.AmTestPermission("Global.SeeHiddenContactInfo", me.BaseLevel) { if database.AmTestPermission("Global.SeeHiddenContactInfo", me.BaseLevel) {
@@ -433,7 +428,7 @@ func ShowProfile(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("mobile", *ci.Mobile) ctxt.VarMap().Set("mobile", *ci.Mobile)
} }
ctxt.VarMap().Set("amsterdam_pageTitle", fmt.Sprintf("User Profile - %s", user.Username)) ctxt.VarMap().Set("amsterdam_pageTitle", fmt.Sprintf("User Profile - %s", user.Username))
return "framed_template", "profile.jet", nil return "framed", "profile.jet"
} }
/* QuickEMail sends quick E-mail to a user. /* QuickEMail sends quick E-mail to a user.
@@ -442,31 +437,30 @@ func ShowProfile(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func QuickEMail(ctxt ui.AmContext) (string, any, error) { func QuickEMail(ctxt ui.AmContext) (string, any) {
me := ctxt.CurrentUser() me := ctxt.CurrentUser()
if me.IsAnon { if me.IsAnon {
return ui.ErrorPage(ctxt, errors.New("you are not logged in")) return "error", "you are not logged in"
} }
myCI, err := me.ContactInfo(ctxt.Ctx()) myCI, err := me.ContactInfo(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
toUid, err := ctxt.FormFieldInt("to_uid") toUid, err := ctxt.FormFieldInt("to_uid")
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
user, err := database.AmGetUser(ctxt.Ctx(), int32(toUid)) user, err := database.AmGetUser(ctxt.Ctx(), int32(toUid))
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
if user.IsAnon { if user.IsAnon {
return ui.ErrorPage(ctxt, errors.New("cannot send quick E-mail to anonymous user")) return "error", "cannot send quick E-mail to anonymous user"
} }
ci, err := user.ContactInfo(ctxt.Ctx()) ci, err := user.ContactInfo(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
msg := email.AmNewEmailMessage(me.Uid, ctxt.RemoteIP()) msg := email.AmNewEmailMessage(me.Uid, ctxt.RemoteIP())
msg.AddTo(*ci.Email, user.Username) msg.AddTo(*ci.Email, user.Username)
@@ -474,7 +468,7 @@ func QuickEMail(ctxt ui.AmContext) (string, any, error) {
msg.SetSubject(ctxt.FormField("subj")) msg.SetSubject(ctxt.FormField("subj"))
msg.SetText(ctxt.FormField("pb")) msg.SetText(ctxt.FormField("pb"))
msg.Send() msg.Send()
return "redirect", "/user/" + user.Username, nil return "redirect", "/user/" + user.Username
} }
/* Hotlist displays and edits the user's conference hotlist. /* Hotlist displays and edits the user's conference hotlist.
@@ -483,16 +477,15 @@ func QuickEMail(ctxt ui.AmContext) (string, any, error) {
* Returns: * Returns:
* Command string dictating what to be rendered. * Command string dictating what to be rendered.
* Data as a parameter for the command string. * Data as a parameter for the command string.
* Standard Go error status.
*/ */
func Hotlist(ctxt ui.AmContext) (string, any, error) { func Hotlist(ctxt ui.AmContext) (string, any) {
me := ctxt.CurrentUser() me := ctxt.CurrentUser()
if me.IsAnon { if me.IsAnon {
return ui.ErrorPage(ctxt, errors.New("you are not logged in")) return "error", "you are not logged in"
} }
hotlist, err := database.AmGetConferenceHotlist(ctxt.Ctx(), me) hotlist, err := database.AmGetConferenceHotlist(ctxt.Ctx(), me)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
if ctxt.HasParameter("m") { if ctxt.HasParameter("m") {
@@ -501,7 +494,7 @@ func Hotlist(ctxt ui.AmContext) (string, any, error) {
if index >= 0 && (index+dir) != index { if index >= 0 && (index+dir) != index {
err := database.AmReorderHotlist(ctxt.Ctx(), me, hotlist[index].Sequence, hotlist[index+dir].Sequence) err := database.AmReorderHotlist(ctxt.Ctx(), me, hotlist[index].Sequence, hotlist[index+dir].Sequence)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
tmp := hotlist[index].CommId tmp := hotlist[index].CommId
hotlist[index].CommId = hotlist[index+dir].CommId hotlist[index].CommId = hotlist[index+dir].CommId
@@ -515,7 +508,7 @@ func Hotlist(ctxt ui.AmContext) (string, any, error) {
if index >= 0 { if index >= 0 {
err := database.AmRemoveEntryFromHotlist(ctxt.Ctx(), me, hotlist[index].Sequence) err := database.AmRemoveEntryFromHotlist(ctxt.Ctx(), me, hotlist[index].Sequence)
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
hotlist = append(hotlist[:index], hotlist[index+1:]...) hotlist = append(hotlist[:index], hotlist[index+1:]...)
} }
@@ -526,12 +519,12 @@ func Hotlist(ctxt ui.AmContext) (string, any, error) {
for i := range hotlist { for i := range hotlist {
comm, err := hotlist[i].Community(ctxt.Ctx()) comm, err := hotlist[i].Community(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
communities[i] = comm.Name communities[i] = comm.Name
conf, err := hotlist[i].Conference(ctxt.Ctx()) conf, err := hotlist[i].Conference(ctxt.Ctx())
if err != nil { if err != nil {
return ui.ErrorPage(ctxt, err) return "error", err
} }
conferences[i] = conf.Name conferences[i] = conf.Name
} }
@@ -540,5 +533,5 @@ func Hotlist(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("communities", communities) ctxt.VarMap().Set("communities", communities)
ctxt.VarMap().Set("conferences", conferences) ctxt.VarMap().Set("conferences", conferences)
ctxt.VarMap().Set("amsterdam_pageTitle", "Your Conference Hotlist") ctxt.VarMap().Set("amsterdam_pageTitle", "Your Conference Hotlist")
return "framed_template", "hotlist.jet", nil return "framed", "hotlist.jet"
} }