hakobox/routes/routes.go
2025-04-21 17:59:57 -03:00

178 lines
3.9 KiB
Go

package routes
import (
"bytes"
"context"
"database/sql"
"errors"
"fmt"
"foobar/database"
"foobar/model"
"foobar/views"
"net/http"
"os"
"path/filepath"
"text/template"
"github.com/prometheus/client_golang/prometheus/promhttp"
"golang.org/x/crypto/bcrypt"
)
const noRedirect redirectURL = ""
var (
mux *http.ServeMux = nil
errBoxNotFound error = fmt.Errorf("box id not found")
staticDir string = filepath.Join("views", "static")
)
var readmeTemplate model.Markdown
func init() {
mux = http.NewServeMux()
if err := os.MkdirAll(staticDir, 777); err != nil {
panic(err)
}
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServerFS(os.DirFS(staticDir))))
mux.HandleFunc("/", index)
mux.HandleFunc("POST /box/{box}", redirectHtmxFormMiddleware(fileUpload))
mux.HandleFunc("GET /box/{box}", getRouteMiddleware(boxUpload))
mux.HandleFunc("GET /box/{box}/inside", getRouteMiddleware(checkBox))
mux.HandleFunc("/panic", func(w http.ResponseWriter, r *http.Request) {
panic("não implementado")
})
mux.Handle("/metrics", promhttp.Handler())
var buf bytes.Buffer
err := template.Must(template.ParseFiles(filepath.Join(staticDir, "default", "README.md"))).
Execute(&buf, nil)
if err != nil {
panic(err)
}
readmeTemplate = mdToHTML(buf.Bytes())
}
func Mux() http.Handler {
return logging(mux)
}
func notFound(w http.ResponseWriter) {
w.WriteHeader(404)
if err := views.FourOfour().Render(context.Background(), w); err != nil {
logInternalError(w, err)
return
}
}
func index(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/index.html" && r.URL.Path != "/" || r.Method != "GET" {
notFound(w)
return
}
if err := views.Index().Render(context.Background(), w); err != nil {
logInternalError(w, err)
return
}
}
func GetBoxURL(r *http.Request) (model.BoxURL, error) {
return model.CheckBoxURL(r.PathValue("box"))
}
// func sobre(w http.ResponseWriter, r *http.Request) {
// if err := views.Sobre().Render(context.Background(), w); err != nil {
// logInternalError(w, err)
// return
// }
// }
// func logIn(w http.ResponseWriter, r *http.Request) {
//
// _, err := currentUser(r)
//
// userLogged := err == nil
//
// if userLogged {
// http.Redirect(w, r, "/logged", http.StatusFound)
// return
// }
//
// if err := views.Login().Render(context.Background(), w); err != nil {
// logInternalError(w, err)
// return
// }
// }
func logInPOST(w http.ResponseWriter, r *http.Request) (redirectURL, error) {
email := r.FormValue("email")
if email == "" {
return "", formValueMissing("email", r)
}
senha := r.FormValue("senha")
if senha == "" {
return "", formValueMissing("senha", r)
}
tx := database.MustBeginTx()
defer tx.Rollback()
usuario, err := database.VerifyUser(tx, email, senha)
if err != nil {
if errors.Is(err, sql.ErrNoRows) || errors.Is(err, bcrypt.ErrMismatchedHashAndPassword) {
return "", newUserError("senha ou email não conferem")
} else {
return "", err
}
}
session, err := store.Get(r, sessionIdCookie)
if err != nil {
return "", err
}
userId, err := usuario.Id()
if err != nil {
return "", err
}
session.Values["userId"] = userId
session.Options.SameSite = http.SameSiteDefaultMode
if err := session.Save(r, w); err != nil {
return "", err
}
return "/logged", nil
}
func logged(w http.ResponseWriter, r *http.Request) {
usuario, err := currentUser(r)
if err != nil {
logError(err)
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Não Autorizado."))
return
}
if err = views.Logged(usuario).Render(context.Background(), w); err != nil {
logInternalError(w, err)
return
}
}
func logout(w http.ResponseWriter, r *http.Request) {
session, err := store.Get(r, sessionIdCookie)
if err != nil {
logInternalError(w, err)
return
}
session.Options.MaxAge = -1
if err = session.Save(r, w); err != nil {
logInternalError(w, err)
return
}
http.Redirect(w, r, "/login", http.StatusFound)
}