84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
package web
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"net/http"
|
||
|
|
"strconv"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"uPortal/internal/auth"
|
||
|
|
)
|
||
|
|
|
||
|
|
// HandleInvites lists all invite codes. Requires a super user.
|
||
|
|
func (s *WebService) HandleInvites(w http.ResponseWriter, r *http.Request) {
|
||
|
|
data, ok := s.basicViewData(w, r, "Invites")
|
||
|
|
if !ok {
|
||
|
|
http.Redirect(w, r, "/signin", http.StatusSeeOther)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
invites, err := s.auths.GetInvites(r.Context(), 1000, 0)
|
||
|
|
if err != nil {
|
||
|
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
data.Invites = invites
|
||
|
|
|
||
|
|
s.render(w, r, "invite/view.html", data)
|
||
|
|
}
|
||
|
|
|
||
|
|
// HandleInviteCreate renders the creation form on GET and mints an invite on POST.
|
||
|
|
func (s *WebService) HandleInviteCreate(w http.ResponseWriter, r *http.Request) {
|
||
|
|
switch r.Method {
|
||
|
|
case http.MethodGet:
|
||
|
|
data, ok := s.basicViewData(w, r, "Create Invite")
|
||
|
|
if !ok {
|
||
|
|
http.Redirect(w, r, "/signin", http.StatusSeeOther)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
s.render(w, r, "invite/create.html", data)
|
||
|
|
|
||
|
|
case http.MethodPost:
|
||
|
|
if err := auth.ValidateCsrf(r, CsrfCookieName, CsrfFieldName); err != nil {
|
||
|
|
s.render(w, r, "invite/create.html", &ViewData{Error: "Invalid form, please try again"})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
uses := int64(1)
|
||
|
|
hours := int64(24)
|
||
|
|
if v, err := strconv.ParseInt(r.FormValue("uses"), 10, 64); err == nil && v > 0 {
|
||
|
|
uses = v
|
||
|
|
}
|
||
|
|
if v, err := strconv.ParseInt(r.FormValue("expires_hours"), 10, 64); err == nil && v > 0 {
|
||
|
|
hours = v
|
||
|
|
}
|
||
|
|
|
||
|
|
expiresAt := time.Now().UTC().Add(time.Duration(hours) * time.Hour)
|
||
|
|
|
||
|
|
token, err := auth.GenerateToken(32)
|
||
|
|
if err != nil {
|
||
|
|
s.render(w, r, "invite/create.html", &ViewData{Error: "Could not generate invite token"})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
if _, err := s.auths.CreateInvite(r.Context(), token, uses, expiresAt); err != nil {
|
||
|
|
s.render(w, r, "invite/create.html", &ViewData{Error: "Could not create invite"})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
http.Redirect(w, r, "/invites", http.StatusSeeOther)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// HandleInviteDelete removes the invite identified by the form field "token".
|
||
|
|
func (s *WebService) HandleInviteDelete(w http.ResponseWriter, r *http.Request) {
|
||
|
|
if err := auth.ValidateCsrf(r, CsrfCookieName, CsrfFieldName); err != nil {
|
||
|
|
http.Redirect(w, r, "/invites", http.StatusSeeOther)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
token := r.FormValue("token")
|
||
|
|
if token != "" {
|
||
|
|
_ = s.auths.DeleteInvite(r.Context(), token)
|
||
|
|
}
|
||
|
|
http.Redirect(w, r, "/invites", http.StatusSeeOther)
|
||
|
|
}
|