| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 | package webimport (	"net/http"	"net/url"	"strings"	"github.com/gin-contrib/sessions"	"github.com/gin-gonic/gin"	csrf "github.com/utrack/gin-csrf")type QueueOp stringconst (	OpDelete  QueueOp = "delete"	OpRedrive QueueOp = "redrive"	OpInvalid QueueOp = "invalid")// getOp extracts the operation from the unsafe form data, returning a safe value.func getOp(u *url.URL) QueueOp {	q := u.Query()	found := 0	var res QueueOp	for key := range q {		switch op := QueueOp(strings.ToLower(key)); op {		case OpDelete, OpRedrive:			res = op			found++		default:			continue		}	}	if found != 1 {		return OpInvalid	}	return res}func parseIDs(u *url.URL) []string {	const prefix = "id-"	q := u.Query()	var ids []string	for k, vs := range q {		// Weed out bad keys, bad value lengths, and non-matching checkbox statuses.		if pos := strings.Index(k, prefix); pos == -1 || len(vs) != 1 || vs[0] != "on" {			continue		}		b, a, found := strings.Cut(k, prefix)		if b == "" && found {			ids = append(ids, a)		}	}	return ids}type confirmData struct {	question, description string	confirm, cancel       string	redirect              string // site-relative path}func makeConfirmHandler() gin.HandlerFunc {	return func(c *gin.Context) {		u := c.Request.URL		op := getOp(u)		var data confirmData		switch op {		case OpDelete:			data = confirmDelete(c)		case OpRedrive:			data = confirmRedrive(c)		default:			data = confirmInvalid(c)		}		ids := parseIDs(u)		sess := sessions.Default(c)		flashes := sess.Flashes()		token := csrf.GetToken(c)		sess.Save()		c.HTML(http.StatusOK, "confirm", gin.H{			"cancel":      "Cancel",			"confirm":     data.confirm,			"csrf":        token,			"description": data.description,			"flashes":     flashes,			"list":        ids,			"question":    data.question,			"redirect":    data.redirect,		})	}}func confirmDelete(c *gin.Context) confirmData {	qName := c.Param("name")	cd := confirmData{		cancel:      "",		confirm:     "Delete",		description: "These messages cannot be recovered after that step",		question:    "Do you confirm this deletion request ?",		redirect:    "/queue/" + qName,	}	if qName == "" {		cd.redirect = "/"	}	return cd}func confirmRedrive(c *gin.Context) confirmData {	cd := confirmData{}	return cd}func confirmInvalid(c *gin.Context) confirmData {	cd := confirmData{}	return cd}
 |