landed add/remove conference alias

This commit is contained in:
2026-02-08 22:23:15 -07:00
parent cc1844cc46
commit 966a3f4924
5 changed files with 139 additions and 6 deletions
+61
View File
@@ -11,6 +11,7 @@
package main
import (
"errors"
"fmt"
"net/http"
@@ -140,15 +141,75 @@ func ConferenceAliasForm(ctxt ui.AmContext) (string, any, error) {
return ui.ErrorPage(ctxt, ENOPERM)
}
ctxt.VarMap().Set("newAlias", "")
ctxt.VarMap().Set("confName", conf.Name)
ctxt.VarMap().Set("backLink", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias")))
ctxt.VarMap().Set("selfLink", fmt.Sprintf("/comm/%s/conf/%s/aliases", comm.Alias, ctxt.GetScratch("currentAlias")))
ctxt.VarMap().Set("amsterdam_pageTitle", fmt.Sprintf("Manage Conference Aliases: %s", conf.Name))
if ctxt.HasParameter("del") {
err := conf.RemoveAlias(ctxt.Ctx(), ctxt.Parameter("del"), ctxt.CurrentUser(), ctxt.RemoteIP())
if err != nil {
ctxt.VarMap().Set("errorMessage", err.Error())
}
}
aliases, err := conf.Aliases(ctxt.Ctx())
if err != nil {
return ui.ErrorPage(ctxt, err)
}
ctxt.VarMap().Set("aliases", aliases)
return "framed_template", "conf_aliases.jet", nil
}
/* ConferenceAliasAdd adds a new alias to the current conference.
* Parameters:
* ctxt - The AmContext for the request.
* Returns:
* Command string dictating what to be rendered.
* Data as a parameter for the command string.
* Standard Go error status.
*/
func ConferenceAliasAdd(ctxt ui.AmContext) (string, any, error) {
comm := ctxt.CurrentCommunity()
conf := ctxt.GetScratch("currentConference").(*database.Conference)
myLevel := ctxt.GetScratch("levelInConference").(uint16)
if !conf.TestPermission("Conference.Change", myLevel) {
ctxt.SetRC(http.StatusForbidden)
return ui.ErrorPage(ctxt, ENOPERM)
}
ctxt.VarMap().Set("confName", conf.Name)
ctxt.VarMap().Set("backLink", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias")))
ctxt.VarMap().Set("selfLink", fmt.Sprintf("/comm/%s/conf/%s/aliases", comm.Alias, ctxt.GetScratch("currentAlias")))
ctxt.VarMap().Set("amsterdam_pageTitle", fmt.Sprintf("Manage Conference Aliases: %s", conf.Name))
newAlias := ctxt.FormField("na")
ctxt.VarMap().Set("newAlias", newAlias)
var err error = nil
if ctxt.FormFieldIsSet("add") {
if database.AmIsValidAmsterdamID(newAlias) {
err = conf.AddAlias(ctxt.Ctx(), newAlias, ctxt.CurrentUser(), ctxt.RemoteIP())
} else {
err = fmt.Errorf("value '%s' is not a valid Amsterdam id", newAlias)
}
} else {
err = errors.New("invalid button press")
}
if err != nil {
ctxt.VarMap().Set("errorMessage", err.Error())
}
aliases, err := conf.Aliases(ctxt.Ctx())
if err != nil {
return ui.ErrorPage(ctxt, err)
}
ctxt.VarMap().Set("newAlias", "")
ctxt.VarMap().Set("aliases", aliases)
return "framed_template", "conf_aliases.jet", nil
}
+57
View File
@@ -141,6 +141,63 @@ func (c *Conference) AliasesQ(ctx context.Context) []string {
return rc
}
// AddAlias adds an alias to the conference.
func (c *Conference) AddAlias(ctx context.Context, alias string, u *User, ipaddr string) error {
row := amdb.QueryRowContext(ctx, "SELECT alias FROM confalias WHERE confid = ? AND alias = ?", c.ConfId, alias)
tmp := ""
err := row.Scan(&tmp)
if err != sql.ErrNoRows {
if err == nil {
return fmt.Errorf("the alias '%s' is already in use by another conference", alias)
}
return err
}
_, err = amdb.ExecContext(ctx, "INSERT INTO confalias (confid, alias) VALUES (?, ?)", c.ConfId, alias)
if err != nil {
return err
}
ar := AmNewAudit(AuditConferenceAlias, u.Uid, ipaddr, fmt.Sprintf("conf=%d", c.ConfId), fmt.Sprintf("add=%s", alias))
AmStoreAudit(ar)
return nil
}
func (c *Conference) RemoveAlias(ctx context.Context, alias string, u *User, ipaddr string) error {
row := amdb.QueryRowContext(ctx, "SELECT COUNT(*) FROM confalias WHERE confid = ?", c.ConfId)
aliasCount := 0
err := row.Scan(&aliasCount)
if err != nil {
return err
}
if aliasCount == 1 {
row = amdb.QueryRowContext(ctx, "SELECT alias FROM confalias WHERE confid = ? AND alias = ?", c.ConfId, alias)
tmp := ""
err = row.Scan(&tmp)
if err == nil {
return errors.New("the conference must have at least one alias")
} else if err != sql.ErrNoRows {
return err
}
}
rs, err := amdb.ExecContext(ctx, "DELETE FROM confalias WHERE confid = ? AND alias = ?", c.ConfId, alias)
if err != nil {
return err
}
rowCount, err := rs.RowsAffected()
if err != nil {
return err
}
if rowCount != 1 {
return errors.New("alias not found")
}
ar := AmNewAudit(AuditConferenceAlias, u.Uid, ipaddr, fmt.Sprintf("conf=%d", c.ConfId), fmt.Sprintf("remove=%s", alias))
AmStoreAudit(ar)
return nil
}
// Hosts returns the list of users that host this conference.
func (c *Conference) Hosts(ctx context.Context) ([]*User, error) {
rs, err := amdb.QueryContext(ctx, "SELECT uid FROM confmember WHERE confid = ? AND granted_lvl = ?",
+3 -3
View File
@@ -63,9 +63,9 @@ _(italicized items can be deferred)_
- ~~Fixseen~~
- ~~Send invite~~
- ~~Change information~~
- Manage aliases
- Remove alias
- Add alias
- ~~Manage aliases~~
- ~~Remove alias~~
- ~~Add alias~~
- Manage members
- Custom appearance
- Activity reports
+1
View File
@@ -115,6 +115,7 @@ func setupEcho() *echo.Echo {
confGroup.GET("/edit", ui.AmWrap(EditConferenceForm))
confGroup.POST("/edit", ui.AmWrap(EditConference))
confGroup.GET("/aliases", ui.AmWrap(ConferenceAliasForm))
confGroup.POST("/aliases", ui.AmWrap(ConferenceAliasAdd))
confGroup.GET("/hotlist", ui.AmWrap(AddToHotlist))
confGroup.GET("/invite", ui.AmWrap(InviteToConference))
confGroup.GET("/r/:topic", ui.AmWrap(ReadPosts), ui.SetTopic)
+17 -3
View File
@@ -16,6 +16,20 @@
<hr class="border-2 border-gray-400 w-4/5 mt-2 mb-6">
</div>
{{ if isset(errorMessage) }}
<!-- Error Message Banner -->
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-6" id="error-banner">
<div class="flex items-center">
<div class="flex-shrink-0">
<span class="text-red-500 text-xl">⚠️</span>
</div>
<div class="ml-3">
<p class="text-sm font-medium" id="error-message">{{ CapitalizeString(errorMessage) }}.</p>
</div>
</div>
</div>
{{ end }}
<!-- Backlink -->
<div class="mb-4">
<a class="text-blue-700 hover:text-blue-900 text-sm font-medium" href="{{ backLink }}">Return to Manage Conference Menu</a>
@@ -29,16 +43,16 @@
<span class="text-sm pt-0.5">🟣</span>
<span class="text-black">{{ a }}</span>
{{ if len(aliases) > 1 }}
<a href="TODO" class="hover:scale-125 inline-block transition-transform" title="Remove">🗙</a>
<a href="{{ selfLink }}?del={{ a }}" class="hover:scale-125 inline-block transition-transform" title="Remove">🗙</a>
{{ end }}
</div>
{{ end }}
</div>
<h2 class="text-blue-800 text-3xl font-bold mb-2">Add New Alias:</h2>
<form method="POST" action="TODO">
<form method="POST" action="{{ selfLink }}">
<div class="flex justify-between items-center mb-2">
<input type="text" id="na" name="na" size="32" maxlength="64" value="" placeholder="New alias..."
<input type="text" id="na" name="na" size="32" maxlength="64" value="{{ newAlias }}" placeholder="New alias..."
class="flex-1 px-3 py-2 border border-gray-300 rounded font-mono focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<button type="submit" name="add" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded font-medium transition-colors">Add</button>
</div>