180 lines
4.1 KiB
Go
180 lines
4.1 KiB
Go
package router
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"database/sql"
|
|
"encoding/hex"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"go.jolheiser.com/invitea/api"
|
|
"go.jolheiser.com/invitea/database"
|
|
"go.jolheiser.com/invitea/static"
|
|
|
|
"code.gitea.io/sdk/gitea"
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
type Routes struct {
|
|
DB *database.Queries
|
|
Gitea *gitea.Client
|
|
GiteaURL string
|
|
}
|
|
|
|
func (ro *Routes) Index(w http.ResponseWriter, r *http.Request) {
|
|
var isAdmin bool
|
|
if ia, ok := r.Context().Value("isAdmin").(bool); ok {
|
|
isAdmin = ia
|
|
}
|
|
|
|
dbInvites, err := ro.DB.ListInvites(r.Context())
|
|
if err != nil {
|
|
log.Err(err).Msg("")
|
|
}
|
|
|
|
if err := static.Templates.ExecuteTemplate(w, "index.tmpl", map[string]any{
|
|
"isAdmin": isAdmin,
|
|
"username": r.Context().Value("username"),
|
|
"invites": api.InvitesFromDB(dbInvites...),
|
|
}); err != nil {
|
|
log.Err(err).Msg("")
|
|
}
|
|
}
|
|
|
|
func (ro *Routes) IndexPost(w http.ResponseWriter, r *http.Request) {
|
|
action := r.FormValue("action")
|
|
if action == "" {
|
|
http.Redirect(w, r, "/", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
switch action {
|
|
case "delete":
|
|
id, err := strconv.ParseInt(r.FormValue("id"), 10, 64)
|
|
if err != nil {
|
|
http.Error(w, "invalid ID", http.StatusBadRequest)
|
|
return
|
|
}
|
|
if err := ro.DB.DeleteInvite(r.Context(), id); err != nil {
|
|
log.Err(err).Msg("could not delete invite")
|
|
http.Error(w, "could not delete invite", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
case "create":
|
|
u := r.FormValue("uses")
|
|
var uses int64
|
|
if u != "" {
|
|
var err error
|
|
if uses, err = strconv.ParseInt(u, 10, 64); err != nil {
|
|
http.Error(w, "invalid uses", http.StatusBadRequest)
|
|
return
|
|
}
|
|
}
|
|
|
|
e := r.FormValue("expiration")
|
|
var expiration int64
|
|
if e != "" {
|
|
ex, err := time.Parse("2006-01-02", e)
|
|
if err != nil {
|
|
http.Error(w, "invalid expiration", http.StatusBadRequest)
|
|
return
|
|
}
|
|
expiration = ex.Unix()
|
|
}
|
|
|
|
code := make([]byte, 5)
|
|
if _, err := rand.Read(code); err != nil {
|
|
log.Err(err).Msg("could not generate code")
|
|
http.Error(w, "could not generate code", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if _, err := ro.DB.CreateInvite(r.Context(), database.CreateInviteParams{
|
|
Code: hex.EncodeToString(code),
|
|
Total: sql.NullInt64{
|
|
Int64: uses,
|
|
Valid: true,
|
|
},
|
|
Expiration: sql.NullInt64{
|
|
Int64: expiration,
|
|
Valid: true,
|
|
},
|
|
}); err != nil {
|
|
log.Err(err).Msg("could not create invite")
|
|
http.Error(w, "could not create invite", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
}
|
|
|
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
|
}
|
|
|
|
func (ro *Routes) Invite(w http.ResponseWriter, r *http.Request) {
|
|
code := chi.URLParam(r, "code")
|
|
|
|
dbInvite, err := ro.DB.GetInvite(r.Context(), code)
|
|
if err != nil {
|
|
log.Err(err).Str("code", code).Msg("could not get invite")
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
|
|
invite := api.InviteFromDB(dbInvite)
|
|
if !invite.Valid() {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
|
|
if err := static.Templates.ExecuteTemplate(w, "invite.tmpl", map[string]any{
|
|
"invite": invite,
|
|
}); err != nil {
|
|
log.Err(err).Msg("")
|
|
}
|
|
}
|
|
|
|
func (ro *Routes) InvitePost(w http.ResponseWriter, r *http.Request) {
|
|
code := chi.URLParam(r, "code")
|
|
|
|
dbInvite, err := ro.DB.GetInvite(r.Context(), code)
|
|
if err != nil {
|
|
log.Err(err).Msg(code)
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
|
|
invite := api.InviteFromDB(dbInvite)
|
|
if !invite.Valid() {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
|
|
username := r.FormValue("username")
|
|
password := r.FormValue("password")
|
|
email := r.FormValue("email")
|
|
|
|
var b bool
|
|
if _, _, err := ro.Gitea.AdminCreateUser(gitea.CreateUserOption{
|
|
Username: username,
|
|
Email: email,
|
|
Password: password,
|
|
MustChangePassword: &b,
|
|
}); err != nil {
|
|
log.Err(err).Msg("could not create user")
|
|
http.Error(w, "could not create user", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err := ro.DB.UpdateInvite(r.Context(), database.UpdateInviteParams{
|
|
ID: dbInvite.ID,
|
|
Uses: dbInvite.Uses + 1,
|
|
}); err != nil {
|
|
log.Err(err).Msg("could not update invite")
|
|
http.Error(w, "could not update invite", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
http.Redirect(w, r, ro.GiteaURL+"/user/login", http.StatusSeeOther)
|
|
}
|